doe 1.1.80

doe is a powerful Rust crate designed to enhance development workflow by providing an extensive collection of useful macros and utility functions. It not only simplifies common tasks but also offers convenient features for clipboard management,robust cryptographic functions,keyboard input, and mouse interaction.
Documentation
#[allow(warnings)]
#[cfg(feature = "images")]
pub mod images {
    use image::GenericImageView;
    use image::ImageFormat;
    use image::{DynamicImage, ImageBuffer, Rgba, RgbaImage};
    /// # image_add_padding
    /// padding_color [[r,g,b,a]]
    /// ```ignore
    /// use doe::images::image_add_padding;
    /// image_add_padding(
    ///     "demo.png",
    ///     [255,255,255,255], 10,
    ///     10,
    ///     "new_demo.png"
    /// );
    /// ````
    ///
    pub fn image_add_padding(
        path: &str,
        padding_color: [u8; 4],
        padding_vertical: u32,
        padding_horisontal: u32,
        new_path: &str,
    ) -> DynamicImage {
        let image = image::open(path).unwrap();
        let (width, height) = (image.width(), image.height());
        let padded_width = width + 2 * padding_horisontal;
        let padded_height = height + 2 * padding_vertical;
        let color = Rgba(padding_color); //color
        let mut padded_image: RgbaImage =
            ImageBuffer::from_pixel(padded_width, padded_height, color);
        for (x, y, pixel) in image.pixels() {
            padded_image.put_pixel(x + padding_horisontal, y + padding_vertical, pixel);
        }
        DynamicImage::ImageRgba8(padded_image)
    }

    pub fn image_resize(path: &str, size: (u32, u32)) -> DynamicImage {
        // 打开图像文件
        let img = image::open(path).expect("无法打开图像文件");
        // 调整图像大小
        let resized_img = img.resize_exact(size.0, size.1, image::imageops::FilterType::Lanczos3);
        resized_img
    }
    /// # image_convert
    /// ```ignore
    /// let new_format = [
    ///     "Png",
    ///     "Jpeg",
    ///     "Gif",
    ///     "WebP",
    ///     "Pnm",
    ///     "Tiff",
    ///     "Tga",
    ///     "Dds",
    ///     "Bmp",
    ///     "Ico",
    ///     "Hdr",
    ///     "OpenExr",
    ///     "Farbfeld",
    ///     "Avif",
    ///     "Qoi",
    /// ]
    /// ```
    /// ```ignore
    /// use doe::images::image_convert;
    /// image_convert("dvwa_23_14.png","Jpeg","demo.jpg");
    /// ```
    ///
    pub fn image_convert(path: &str, new_format: &str, new_path: &str) {
        // 打开图像文件
        let img = image::open(path).expect("无法打开图像文件");
        let format = match new_format.as_ref() {
            "Png" => (ImageFormat::Png, "png"),
            "Jpeg" => (ImageFormat::Jpeg, "jpg"),
            "Gif" => (ImageFormat::Gif, "gif"),
            "WebP" => (ImageFormat::WebP, "webp"),
            "Pnm" => (ImageFormat::Pnm, "pnm"),
            "Tiff" => (ImageFormat::Tiff, "tiff"),
            "Tga" => (ImageFormat::Tga, "tga"),
            "Dds" => (ImageFormat::Dds, "dds"),
            "Bmp" => (ImageFormat::Bmp, "bmp"),
            "Ico" => (ImageFormat::Ico, "ico"),
            "Hdr" => (ImageFormat::Hdr, "hdr"),
            "OpenExr" => (ImageFormat::OpenExr, "exr"),
            "Farbfeld" => (ImageFormat::Farbfeld, "ff"),
            "Avif" => (ImageFormat::Avif, "avif"),
            "Qoi" => (ImageFormat::Qoi, "qoi"),
            _ => (ImageFormat::Png, "png"),
        };
        img.save_with_format(new_path, format.0).unwrap();
    }

    pub fn convert_to_icns(
        png_path: &str,
        icns_path: &str,
    ) -> Result<(), Box<dyn std::error::Error>> {
        use icns::{IconFamily, IconType, Image};
        let file = std::io::BufReader::new(std::fs::File::open(png_path).unwrap());
        let image = Image::read_png(file).unwrap();
        let w = image.width();
        let h = image.height();
        let new_file = std::io::BufWriter::new(std::fs::File::create(icns_path).unwrap());
        let mut icon_family = IconFamily::new();
        icon_family.add_icon(&image).unwrap();
        icon_family.write(new_file).unwrap();
        Ok(())
    }
    /// # rotate_image
    /// ```ignore
    /// let p_name = "demo.png";
    /// let rotated_img = doe::images::rotate_image(&p_name, 15.0);
    /// rotated_img.save(p_name).expect("Failed to save rotated image");
    /// ```
    /// 
    /// 
    pub fn rotate_image(path: &str, degrees: f32) -> RgbaImage {
        let img = image::open(path).expect("Failed to open image");
        // Calculate the radians equivalent of the given degrees
        let radians = degrees.to_radians();

        // Compute the dimensions of the rotated image
        let (width, height) = img.dimensions();
        let rotated_width =
            ((radians.cos() * width as f32).abs() + (radians.sin() * height as f32).abs()) as u32;
        let rotated_height =
            ((radians.sin() * width as f32).abs() + (radians.cos() * height as f32).abs()) as u32;

        // Create a new blank image with the rotated dimensions
        let mut rotated_img = RgbaImage::new(rotated_width, rotated_height);

        // Compute the center coordinates of the rotated image
        let center_x = rotated_width as f32 / 2.0;
        let center_y = rotated_height as f32 / 2.0;

        // Iterate over each pixel in the rotated image and copy the corresponding pixel from the original image
        for (x, y, pixel) in rotated_img.enumerate_pixels_mut() {
            // Compute the corresponding coordinates in the original image
            let orig_x = radians.cos() * ((x as f32 - center_x) / center_x)
                + radians.sin() * ((y as f32 - center_y) / center_y);
            let orig_y = -radians.sin() * ((x as f32 - center_x) / center_x)
                + radians.cos() * ((y as f32 - center_y) / center_y);

            // Convert the floating-point coordinates to integer coordinates
            let orig_x = orig_x * center_x + center_x;
            let orig_y = orig_y * center_y + center_y;

            // Check if the computed coordinates are within the bounds of the original image
            if orig_x >= 0.0 && orig_x < width as f32 && orig_y >= 0.0 && orig_y < height as f32 {
                // Get the pixel value from the original image
                let orig_pixel = img.get_pixel(orig_x as u32, orig_y as u32);

                // Set the corresponding pixel in the rotated image
                *pixel = Rgba([orig_pixel[0], orig_pixel[1], orig_pixel[2], orig_pixel[3]]);
            }
        }

        rotated_img
    }


    pub fn cut_area(img: ImageBuffer<Rgba<u8>, Vec<u8>>, x: u32, y: u32, width: u32, height: u32) -> Option<RgbaImage> {
        let sub_image = img.view(x, y, width, height);
        let mut cut_image = RgbaImage::new(width, height);
        for (x, y, pixel) in sub_image.pixels() {
            cut_image.put_pixel(x, y, pixel);
        }
        Some(cut_image)
    }
    
    pub fn convert_to_ico(
        png_path: &str,
        ico_path: &str,
    ) -> Result<(), Box<dyn std::error::Error>> {
        use std::fs::write;
        use std::fs::File;
        use std::io::Write;
        // Create a new, empty icon collection:
        let mut icon_dir = ico::IconDir::new(ico::ResourceType::Icon);
        // Read a PNG file from disk and add it to the collection:
        let file = std::fs::File::open(png_path).unwrap();
        let image = ico::IconImage::read_png(file).unwrap();
        icon_dir.add_entry(ico::IconDirEntry::encode(&image).unwrap());
        let file = std::fs::File::create(ico_path).unwrap();
        icon_dir.write(file).unwrap();
        Ok(())
    }
}
#[cfg(feature = "images")]
pub use images::*;