From 4e1687faccbf73803aba9cfc71cd04f3d5e7dee3 Mon Sep 17 00:00:00 2001 From: Torben Ewert Date: Fri, 28 May 2021 09:15:50 +0200 Subject: [PATCH] bugfix: fix diff image generation --- lib/OSnap_Diff/OSnap_Diff.re | 123 +++++++++++++++++++------------- lib/OSnap_Diff/OSnap_Diff_Io.re | 40 ++--------- 2 files changed, 77 insertions(+), 86 deletions(-) diff --git a/lib/OSnap_Diff/OSnap_Diff.re b/lib/OSnap_Diff/OSnap_Diff.re index e2cc489..21c90b1 100644 --- a/lib/OSnap_Diff/OSnap_Diff.re +++ b/lib/OSnap_Diff/OSnap_Diff.re @@ -5,25 +5,15 @@ type failState = | Pixel(int, float) | Layout; -let merge_rgba = (src, dst) => { - let (src_r, src_g, src_b, src_a) = src; - let (dst_r, dst_g, dst_b, dst_a) = dst; - if (src_a == 0) { - dst; - } else if (src_a == 255) { - src; - } else { - let alpha = 255 - src_a; - let r = - alpha * dst_r * dst_a / 255 + src_r * src_a |> min(255) |> max(0); - let g = - alpha * dst_g * dst_a / 255 + src_g * src_a |> min(255) |> max(0); - let b = - alpha * dst_b * dst_a / 255 + src_b * src_a |> min(255) |> max(0); - let a = 255 - alpha * (255 - dst_a) / 255 |> min(255) |> max(0); - - (r, g, b, a); - }; +type point_rect = { + min_x: int, + max_x: int, + min_y: int, + max_y: int, +}; + +let is_in_rect = (x, y, rect) => { + x >= rect.min_x && x <= rect.max_x && y >= rect.min_y && y <= rect.max_y; }; let diff = (~output, ~diffPixel=(255, 0, 0), ~threshold=0, path1, path2) => { @@ -47,53 +37,84 @@ let diff = (~output, ~diffPixel=(255, 0, 0), ~threshold=0, path1, path2) => { Result.ok() | Layout => Result.error(Layout) | Pixel((diff_mask, diffCount, diffPercentage)) => { + let border_width = 5; + let complete_width = - original_image.width + diff_mask.width + new_image.width; + original_image.width + + border_width + + diff_mask.width + + border_width + + new_image.width; + let complete_height = original_image.height |> max(diff_mask.height) |> max(new_image.height); + let complete_image = Image.create_rgb(~alpha=true, complete_width, complete_height); - for (y in 0 to complete_height - 1) { - let diff_row = Io.PNG.readRow(diff_mask, y); - for (x in 0 to complete_width - 1) { - let write = Image.write_rgba(complete_image, x, y); - if (x < original_image.width) { - if (y < original_image.height) { - let (r, g, b, a) = - Io.PNG.readDirectPixel(~x, ~y, original_image); - write(r, g, b, a); - }; - } else if (x >= original_image.width - - 1 - && x < diff_mask.width - + original_image.width) { - if (y < diff_mask.height) { - let read_x = x - original_image.width; + let original_rect = { + min_x: 1, + min_y: 1, + max_x: original_image.width, + max_y: original_image.height, + }; + let diff_rect = { + min_x: original_rect.max_x + border_width + 1, + min_y: 1, + max_x: original_rect.max_x + border_width + diff_mask.width, + max_y: diff_mask.height, + }; + let new_rect = { + min_x: diff_rect.max_x + border_width + 1, + min_y: 1, + max_x: diff_rect.max_x + border_width + new_image.width, + max_y: new_image.height, + }; + for (y in 1 to complete_height) { + for (x in 1 to complete_width) { + let write = Image.write_rgba(complete_image, x - 1, y - 1); + let is_in_rect = is_in_rect(x, y); + + if (is_in_rect(original_rect)) { + let read_x = x - original_rect.min_x; + let read_y = y - original_rect.min_y; + + let (r, g, b, a) = + Io.PNG.readDirectPixel(~x=read_x, ~y=read_y, original_image); + + write(r, g, b, a); + } else if (is_in_rect(diff_rect)) { + let read_x = x - diff_rect.min_x; + let read_y = y - diff_rect.min_y; + + let (r, g, b, a) = + Io.PNG.readDirectPixel(~x=read_x, ~y=read_y, diff_mask); + + if (a != 0) { + write(r, g, b, a); + } else { let (r, g, b, a) = - Io.PNG.readDirectPixel(~x=read_x, ~y, original_image); + Io.PNG.readDirectPixel( + ~x=read_x, + ~y=read_y, + original_image, + ); let brightness = (r * 54 + g * 182 + b * 19) / 255; let mono = min(255, brightness + 80); - let mono = (mono, mono, mono, a); - - let diff_mask_color = - Io.PNG.readImgColor(read_x, diff_row, diff_mask); - let (r, g, b, a) = mono |> merge_rgba(diff_mask_color); - write(r, g, b, a); + write(mono, mono, mono, a); }; - } else if (x >= original_image.width + diff_mask.width) { - if (y < new_image.height) { - let read_x = x - (original_image.width + diff_mask.width); + } else if (is_in_rect(new_rect)) { + let read_x = x - new_rect.min_x; + let read_y = y - new_rect.min_y; - let (r, g, b, a) = - Io.PNG.readDirectPixel(~x=read_x, ~y, new_image); - write(r, g, b, a); - }; + let (r, g, b, a) = + Io.PNG.readDirectPixel(~x=read_x, ~y=read_y, new_image); + write(r, g, b, a); } else { - (); + write(0, 0, 0, 0); }; }; }; diff --git a/lib/OSnap_Diff/OSnap_Diff_Io.re b/lib/OSnap_Diff/OSnap_Diff_Io.re index 7bfff67..de34878 100644 --- a/lib/OSnap_Diff/OSnap_Diff_Io.re +++ b/lib/OSnap_Diff/OSnap_Diff_Io.re @@ -1,12 +1,8 @@ open Odiff; open Odiff.ImageIO; -open Bigarray; module PNG: ImageIO.ImageIO = { - type t = { - image: Image.image, - pixel_cache: Array1.t(int, int_elt, c_layout), - }; + type t = {image: Image.image}; type row = int; let readRow = (_, y) => y; @@ -20,8 +16,7 @@ module PNG: ImageIO.ImageIO = { width, height, image: { - image, - pixel_cache: Array1.create(int, c_layout, width * height), + image: image, }, }; }; @@ -34,35 +29,11 @@ module PNG: ImageIO.ImageIO = { }; let readDirectPixel = (~x, ~y, img: ImageIO.img(t)) => { - let index = y * img.width + x; - let color = Array1.get(img.image.pixel_cache, index); - let a = color lsr 24 land 0xFF; - let r = color lsr 16 land 0xFF; - let g = color lsr 8 land 0xFF; - let b = color land 0xFF; - - (r, g, b, a); + Image.read_rgba(img.image.image, x, y, (r, g, b, a) => (r, g, b, a)); }; let readImgColor = (x, y, img: ImageIO.img(t)) => { - Image.read_rgba( - img.image.image, - x, - y, - (r, g, b, a) => { - let alpha_channel = (a land 0xFF) lsl 24; - let blue_channel = (b land 0xFF) lsl 16; - let green_channel = (g land 0xFF) lsl 8; - let red_channel = r land 0xFF; - - let color = - alpha_channel lor blue_channel lor green_channel lor red_channel; - let index = y * img.width + x; - Array1.set(img.image.pixel_cache, index, color); - - (r, g, b, a); - }, - ); + readDirectPixel(~x, ~y, img); }; let setImgColor = (x, y, (r, g, b), img: ImageIO.img(t)) => { @@ -77,8 +48,7 @@ module PNG: ImageIO.ImageIO = { { ...img, image: { - ...img.image, - image, + image: image, }, }; }; -- 2.51.2