feat: Implement crush and save to png
This commit is contained in:
@@ -83,6 +83,44 @@ impl MSCanvas {
|
||||
self.pixels.clone()
|
||||
}
|
||||
|
||||
pub fn get_pixels_scale(&self, scale: i32) -> Vec<u8> {
|
||||
if scale <= 1 {
|
||||
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
|
||||
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
// 源像素索引
|
||||
let src_idx = ((y * self.width + x) * 4) as usize;
|
||||
|
||||
// 源像素颜色
|
||||
let r = self.pixels[src_idx];
|
||||
let g = self.pixels[src_idx + 1];
|
||||
let b = self.pixels[src_idx + 2];
|
||||
let a = self.pixels[src_idx + 3];
|
||||
|
||||
// 在目标图像中填充 scale×scale 区域
|
||||
for dy in 0..scale {
|
||||
for dx in 0..scale {
|
||||
let dst_x = x * scale + dx;
|
||||
let dst_y = y * scale + dy;
|
||||
let dst_idx = ((dst_y * dst_width + dst_x) * 4) as usize;
|
||||
|
||||
dst[dst_idx] = r;
|
||||
dst[dst_idx + 1] = g;
|
||||
dst[dst_idx + 2] = b;
|
||||
dst[dst_idx + 3] = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dst
|
||||
}
|
||||
|
||||
pub fn pixel_at(&self, x: i32, y: i32) -> MSColor {
|
||||
// 边界检查
|
||||
if x < 0 || x >= self.width || y < 0 || y >= self.height as i32 {
|
||||
@@ -118,6 +156,25 @@ impl MSCanvas {
|
||||
self.pixels[index + 3] = self.color.a; // A
|
||||
}
|
||||
|
||||
pub fn draw_pixel_color_at(&mut self, point: Point, color: MSColor) {
|
||||
let Point { x, y } = point;
|
||||
let x = x as i32;
|
||||
let y = y as i32;
|
||||
// 边界检查
|
||||
if x < 0 || x >= self.width || y < 0 || y >= self.height {
|
||||
return;
|
||||
}
|
||||
// 计算索引:(y * width + x) * 4
|
||||
let index = ((y * self.width + x) * 4) as usize;
|
||||
|
||||
// 写入 RGBA 数据
|
||||
// 注意:Color 的 r, g, b, a 是 0.0 - 1.0,需要转为 0 - 255
|
||||
self.pixels[index] = color.r; // R
|
||||
self.pixels[index + 1] = color.g; // G
|
||||
self.pixels[index + 2] = color.b; // B
|
||||
self.pixels[index + 3] = color.a; // A
|
||||
}
|
||||
|
||||
fn draw_pixel_at1(&mut self, x: i32, y: i32) {
|
||||
// 边界检查
|
||||
if x < 0 || x >= self.width || y < 0 || y >= self.height {
|
||||
@@ -160,6 +217,17 @@ impl MSCanvas {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_cross_color(&mut self, point: Point, color: MSColor) {
|
||||
let Point { x, y } = point;
|
||||
let r = 5;
|
||||
for dy in -r..=r {
|
||||
self.draw_pixel_color_at(Point::new(point.x, point.y + dy as f32), color);
|
||||
}
|
||||
for dx in -r..=r {
|
||||
self.draw_pixel_color_at(Point::new(point.x + dx as f32, point.y), color);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn brush_circle(&mut self, center: Point) {
|
||||
if self.line_width <= 1 {
|
||||
self.draw_pixel_at(center);
|
||||
@@ -191,6 +259,27 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
fn bresenham_line(&mut self, begin: Point, end: Point) -> Vec<Point> {
|
||||
let x1 = begin.x;
|
||||
let y1 = begin.y;
|
||||
@@ -433,6 +522,10 @@ impl MSCanvas {
|
||||
}
|
||||
|
||||
pub fn stroke_rect(&mut self, x: i32, y: i32, width: i32, height: i32) {
|
||||
if width < 2 * self.line_width || height < 2 * self.line_width {
|
||||
self.fill_rect(x, y, width, height);
|
||||
return;
|
||||
}
|
||||
self.fill_rect(x, y, width, self.line_width);
|
||||
self.fill_rect(x, y + height - self.line_width, width, self.line_width);
|
||||
self.fill_rect(x, y, self.line_width, height);
|
||||
@@ -440,6 +533,7 @@ impl MSCanvas {
|
||||
}
|
||||
|
||||
pub fn stroke_rect1(&mut self, p1: Point, p2: Point) {
|
||||
self.draw_cross_color(p1, MSColor::new(255, 0, 0, 255));
|
||||
let mut x = p1.x;
|
||||
let mut y = p1.y;
|
||||
let mut width = (p2.x - p1.x);
|
||||
|
||||
Reference in New Issue
Block a user