1#[allow(warnings)]
2#[cfg(feature = "images")]
3pub mod images {
4 use image::GenericImageView;
5 use image::ImageFormat;
6 use image::{DynamicImage, ImageBuffer, Rgba, RgbaImage};
7 pub fn image_add_padding(
20 path: &str,
21 padding_color: [u8; 4],
22 padding_vertical: u32,
23 padding_horisontal: u32,
24 new_path: &str,
25 ) -> DynamicImage {
26 let image = image::open(path).unwrap();
27 let (width, height) = (image.width(), image.height());
28 let padded_width = width + 2 * padding_horisontal;
29 let padded_height = height + 2 * padding_vertical;
30 let color = Rgba(padding_color); let mut padded_image: RgbaImage =
32 ImageBuffer::from_pixel(padded_width, padded_height, color);
33 for (x, y, pixel) in image.pixels() {
34 padded_image.put_pixel(x + padding_horisontal, y + padding_vertical, pixel);
35 }
36 DynamicImage::ImageRgba8(padded_image)
37 }
38
39 pub fn image_resize(path: &str, size: (u32, u32)) -> DynamicImage {
40 let img = image::open(path).expect("无法打开图像文件");
42 let resized_img = img.resize_exact(size.0, size.1, image::imageops::FilterType::Lanczos3);
44 resized_img
45 }
46 pub fn image_convert(path: &str, new_format: &str, new_path: &str) {
72 let img = image::open(path).expect("无法打开图像文件");
74 let format = match new_format.as_ref() {
75 "Png" => (ImageFormat::Png, "png"),
76 "Jpeg" => (ImageFormat::Jpeg, "jpg"),
77 "Gif" => (ImageFormat::Gif, "gif"),
78 "WebP" => (ImageFormat::WebP, "webp"),
79 "Pnm" => (ImageFormat::Pnm, "pnm"),
80 "Tiff" => (ImageFormat::Tiff, "tiff"),
81 "Tga" => (ImageFormat::Tga, "tga"),
82 "Dds" => (ImageFormat::Dds, "dds"),
83 "Bmp" => (ImageFormat::Bmp, "bmp"),
84 "Ico" => (ImageFormat::Ico, "ico"),
85 "Hdr" => (ImageFormat::Hdr, "hdr"),
86 "OpenExr" => (ImageFormat::OpenExr, "exr"),
87 "Farbfeld" => (ImageFormat::Farbfeld, "ff"),
88 "Avif" => (ImageFormat::Avif, "avif"),
89 "Qoi" => (ImageFormat::Qoi, "qoi"),
90 _ => (ImageFormat::Png, "png"),
91 };
92 img.save_with_format(new_path, format.0).unwrap();
93 }
94
95 pub fn convert_to_icns(
96 png_path: &str,
97 icns_path: &str,
98 ) -> Result<(), Box<dyn std::error::Error>> {
99 use icns::{IconFamily, IconType, Image};
100 let file = std::io::BufReader::new(std::fs::File::open(png_path).unwrap());
101 let image = Image::read_png(file).unwrap();
102 let w = image.width();
103 let h = image.height();
104 let new_file = std::io::BufWriter::new(std::fs::File::create(icns_path).unwrap());
105 let mut icon_family = IconFamily::new();
106 icon_family.add_icon(&image).unwrap();
107 icon_family.write(new_file).unwrap();
108 Ok(())
109 }
110 pub fn rotate_image(path: &str, degrees: f32) -> RgbaImage {
119 let img = image::open(path).expect("Failed to open image");
120 let radians = degrees.to_radians();
122
123 let (width, height) = img.dimensions();
125 let rotated_width =
126 ((radians.cos() * width as f32).abs() + (radians.sin() * height as f32).abs()) as u32;
127 let rotated_height =
128 ((radians.sin() * width as f32).abs() + (radians.cos() * height as f32).abs()) as u32;
129
130 let mut rotated_img = RgbaImage::new(rotated_width, rotated_height);
132
133 let center_x = rotated_width as f32 / 2.0;
135 let center_y = rotated_height as f32 / 2.0;
136
137 for (x, y, pixel) in rotated_img.enumerate_pixels_mut() {
139 let orig_x = radians.cos() * ((x as f32 - center_x) / center_x)
141 + radians.sin() * ((y as f32 - center_y) / center_y);
142 let orig_y = -radians.sin() * ((x as f32 - center_x) / center_x)
143 + radians.cos() * ((y as f32 - center_y) / center_y);
144
145 let orig_x = orig_x * center_x + center_x;
147 let orig_y = orig_y * center_y + center_y;
148
149 if orig_x >= 0.0 && orig_x < width as f32 && orig_y >= 0.0 && orig_y < height as f32 {
151 let orig_pixel = img.get_pixel(orig_x as u32, orig_y as u32);
153
154 *pixel = Rgba([orig_pixel[0], orig_pixel[1], orig_pixel[2], orig_pixel[3]]);
156 }
157 }
158
159 rotated_img
160 }
161
162
163 pub fn cut_area(img: ImageBuffer<Rgba<u8>, Vec<u8>>, x: u32, y: u32, width: u32, height: u32) -> Option<RgbaImage> {
164 let sub_image = img.view(x, y, width, height);
165 let mut cut_image = RgbaImage::new(width, height);
166 for (x, y, pixel) in sub_image.pixels() {
167 cut_image.put_pixel(x, y, pixel);
168 }
169 Some(cut_image)
170 }
171
172 pub fn convert_to_ico(
173 png_path: &str,
174 ico_path: &str,
175 ) -> Result<(), Box<dyn std::error::Error>> {
176 use std::fs::write;
177 use std::fs::File;
178 use std::io::Write;
179 let mut icon_dir = ico::IconDir::new(ico::ResourceType::Icon);
181 let file = std::fs::File::open(png_path).unwrap();
183 let image = ico::IconImage::read_png(file).unwrap();
184 icon_dir.add_entry(ico::IconDirEntry::encode(&image).unwrap());
185 let file = std::fs::File::create(ico_path).unwrap();
186 icon_dir.write(file).unwrap();
187 Ok(())
188 }
189}
190#[cfg(feature = "images")]
191pub use images::*;