diff --git a/.gitignore b/.gitignore index 0b188bc..155142a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ target/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ + +mspaint.png diff --git a/src/mscanvas.rs b/src/mscanvas.rs index 2c578cc..7e4e8a7 100644 --- a/src/mscanvas.rs +++ b/src/mscanvas.rs @@ -88,8 +88,8 @@ impl MSCanvas { return self.pixels.clone(); } let dst_width = self.width * scale; - let dst_height = self.width * scale; - let mut dst = vec![0; (self.width * self.width * 4) as usize]; // RGBA + let dst_height = self.height * scale; + let mut dst = vec![0; (dst_width * dst_height * 4) as usize]; // RGBA for y in 0..self.height { for x in 0..self.width { @@ -262,21 +262,28 @@ impl MSCanvas { pub fn brush_slash(&mut self, center: Point) { let r = self.line_width / 2; let l = self.line_width - r; - // for dx in -1..1 { - // for d in -l..r { - // self.draw_pixel_at(Point::new(center.x - (d as f32) + (dx as f32), center.y - d as f32)); - // } - // } - for d in -l..r { - self.draw_pixel_at(Point::new(center.x - (d as f32), center.y - d as f32)); + // 左右扩展,填补线条的空白 + for dx in 0..2 { + for d in -l..r { + self.draw_pixel_at(Point::new( + center.x - (d as f32) + (dx as f32), + center.y - d as f32, + )); + } } } pub fn brush_backslash(&mut self, center: Point) { let r = self.line_width / 2; let l = self.line_width - r; - for d in -l..r { - self.draw_pixel_at(Point::new(center.x + d as f32, center.y - d as f32)); + // 左右扩展,填补线条的空白 + for dx in 0..2 { + for d in -l..r { + self.draw_pixel_at(Point::new( + center.x + d as f32 + (dx as f32), + center.y - d as f32, + )); + } } } diff --git a/src/paint.rs b/src/paint.rs index d3815b8..387c976 100644 --- a/src/paint.rs +++ b/src/paint.rs @@ -1,4 +1,4 @@ -use ::image::RgbaImage; +use ::image::{ImageBuffer, ImageError, Rgba}; use iced::Theme; use iced::padding; use iced::widget::container; @@ -360,13 +360,14 @@ impl PaintApp { let scale = 4; let (width, height) = self.canvas.size(); let pixels = self.canvas.get_pixels_scale(4); - save_rgba_as_png( + save_rgba_to_png( pixels, (width * scale) as u32, (height * scale) as u32, "mspaint.png", ) .unwrap(); + println!("save png"); } Message::RefreshImage => { if self.dirty { @@ -582,23 +583,16 @@ pub fn main() -> iced::Result { .run() } -fn save_rgba_as_png( - pixels: Vec, +fn save_rgba_to_png( + rgba_data: Vec, width: u32, height: u32, path: &str, -) -> Result<(), Box> { - // 验证像素数量是否匹配 - if pixels.len() != (width * height * 4) as usize { - return Err("Pixel buffer size does not match width × height × 4".into()); - } +) -> Result<(), ImageError> { + // Each pixel is 4 bytes (R, G, B, A) + let img: ImageBuffer, Vec> = ImageBuffer::from_raw(width, height, rgba_data) + .expect("Failed to create ImageBuffer: data size mismatch"); - // 创建 RgbaImage - let img: RgbaImage = RgbaImage::from_vec(width, height, pixels) - .ok_or("Failed to create image from pixel data")?; - - // 保存为 PNG(保留 Alpha 通道) img.save(path)?; - Ok(()) }