mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/utils/image.rs')
-rw-r--r--src/utils/image.rs84
1 files changed, 64 insertions, 20 deletions
diff --git a/src/utils/image.rs b/src/utils/image.rs
index 867d1fc..de6cf6b 100644
--- a/src/utils/image.rs
+++ b/src/utils/image.rs
@@ -1,27 +1,71 @@
+use fast_image_resize as fr;
use image::{Rgb, Rgba, RgbaImage};
+use std::num::NonZeroU32;
+pub trait ImageUtils {
+ fn tint(&mut self, color: Rgb<u8>) -> &mut Self;
-pub fn tint(image: &mut RgbaImage, color: Rgb<u8>) {
- let [tr, tg, tb] = [
- color[0] as f32 / 255.0,
- color[1] as f32 / 255.0,
- color[2] as f32 / 255.0,
- ];
- for Rgba([r, g, b, _]) in image.pixels_mut() {
- *r = (*r as f32 * tr) as u8;
- *g = (*g as f32 * tg) as u8;
- *b = (*b as f32 * tb) as u8;
- }
+ fn repeat(&mut self, with: &RgbaImage) -> &mut Self;
+
+ fn overlay(&mut self, with: &RgbaImage, x: u32, y: u32) -> &mut Self;
+
+ unsafe fn scale(self, to: u32) -> Self;
}
-pub fn repeat(to: &mut RgbaImage, from: &RgbaImage) {
- for x in 0..(to.width() / from.width()) {
- for y in 0..(to.height() / from.height()) {
- image::imageops::overlay(
- to,
- from,
- (x * from.width()).into(),
- (y * from.height()).into(),
- );
+impl ImageUtils for RgbaImage {
+ fn tint(&mut self, color: Rgb<u8>) -> &mut Self {
+ let [tr, tg, tb] = [
+ color[0] as f32 / 255.0,
+ color[1] as f32 / 255.0,
+ color[2] as f32 / 255.0,
+ ];
+ for Rgba([r, g, b, _]) in self.pixels_mut() {
+ *r = (*r as f32 * tr) as u8;
+ *g = (*g as f32 * tg) as u8;
+ *b = (*b as f32 * tb) as u8;
+ }
+ self
+ }
+
+ fn repeat(&mut self, with: &RgbaImage) -> &mut Self {
+ for x in 0..(self.width() / with.width()) {
+ for y in 0..(self.height() / with.height()) {
+ self.overlay(with, x * with.width(), y * with.height());
+ }
}
+ self
+ }
+
+ fn overlay(&mut self, with: &RgbaImage, x: u32, y: u32) -> &mut Self {
+ for j in 0..with.height() {
+ for i in 0..with.width() {
+ let get = with.get_pixel(i, j);
+ if get[3] > 5 {
+ self.put_pixel(i + x, j + y, *get);
+ }
+ }
+ }
+ self
+ }
+
+ /// scales a image
+ ///
+ /// SAFETY: to and width and height cannot be 0.
+ unsafe fn scale(self, to: u32) -> Self {
+ debug_assert_ne!(to, 0);
+ debug_assert_ne!(self.width(), 0);
+ debug_assert_ne!(self.height(), 0);
+ let to = NonZeroU32::new_unchecked(to);
+ let src = fr::Image::from_vec_u8(
+ NonZeroU32::new_unchecked(self.width()),
+ NonZeroU32::new_unchecked(self.height()),
+ self.into_vec(),
+ fr::PixelType::U8x4,
+ )
+ .unwrap();
+ let mut dst = fr::Image::new(to, to, fr::PixelType::U8x4);
+ fr::Resizer::new(fr::ResizeAlg::Nearest)
+ .resize(&src.view(), &mut dst.view_mut())
+ .unwrap();
+ RgbaImage::from_raw(to.get(), to.get(), dst.into_vec()).unwrap()
}
}