use image::{Rgba, RgbaImage};
use crate::region::Region;
const BOX_FILL_ALPHA: f64 = 0.15;
const BOX_BORDER_WIDTH: u32 = 2;
const PALETTE: [[u8; 3]; 16] = [
[230, 25, 75], [60, 180, 75], [0, 130, 200], [255, 225, 25], [245, 130, 48], [145, 30, 180], [70, 240, 240], [240, 50, 230], [210, 245, 60], [250, 190, 212], [0, 128, 128], [220, 190, 255], [170, 110, 40], [255, 250, 200], [128, 0, 0], [170, 255, 195], ];
pub fn render_diff_image(
candidate: &RgbaImage,
_diff_mask: &[bool],
_component_labels: &[u32],
regions: &[Region],
) -> RgbaImage {
let (width, height) = candidate.dimensions();
let mut output = candidate.clone();
for (idx, region) in regions.iter().enumerate() {
let bb = ®ion.bounding_box;
let c = PALETTE[idx % PALETTE.len()];
let x_end = (bb.x + bb.width).min(width);
let y_end = (bb.y + bb.height).min(height);
for y in bb.y..y_end {
for x in bb.x..x_end {
let px = output.get_pixel(x, y);
let r = (c[0] as f64 * BOX_FILL_ALPHA + px[0] as f64 * (1.0 - BOX_FILL_ALPHA)) as u8;
let g = (c[1] as f64 * BOX_FILL_ALPHA + px[1] as f64 * (1.0 - BOX_FILL_ALPHA)) as u8;
let b = (c[2] as f64 * BOX_FILL_ALPHA + px[2] as f64 * (1.0 - BOX_FILL_ALPHA)) as u8;
output.put_pixel(x, y, Rgba([r, g, b, 255]));
}
}
draw_rect(&mut output, bb.x, bb.y, bb.width, bb.height, Rgba([c[0], c[1], c[2], 255]), BOX_BORDER_WIDTH);
}
output
}
fn draw_rect(img: &mut RgbaImage, x: u32, y: u32, w: u32, h: u32, color: Rgba<u8>, stroke: u32) {
let (img_w, img_h) = img.dimensions();
let x0 = x.saturating_sub(stroke);
let y0 = y.saturating_sub(stroke);
let x1 = (x + w + stroke - 1).min(img_w - 1);
let y1 = (y + h + stroke - 1).min(img_h - 1);
for py in 0..stroke {
for px in x0..=x1 {
let top = y0 + py;
let bot = y1 - py;
if top < img_h {
img.put_pixel(px, top, color);
}
if bot < img_h {
img.put_pixel(px, bot, color);
}
}
}
for px in 0..stroke {
for py in y0..=y1 {
let left = x0 + px;
let right = x1 - px;
if left < img_w {
img.put_pixel(left, py, color);
}
if right < img_w {
img.put_pixel(right, py, color);
}
}
}
}