From 0609cdb4cd27b543f6926e53a0baac86c34945fa Mon Sep 17 00:00:00 2001 From: Meizar Rimadana Date: Sun, 27 Jul 2025 16:09:11 +0700 Subject: [PATCH] cropping feature --- WebApp/ImageGenerator.cs | 63 +++++++++++++++++++++++++++++++++------- WebApp/RequestBody.cs | 4 +++ 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/WebApp/ImageGenerator.cs b/WebApp/ImageGenerator.cs index 44955f9..3d29be6 100644 --- a/WebApp/ImageGenerator.cs +++ b/WebApp/ImageGenerator.cs @@ -54,7 +54,7 @@ public class ImageGenerator double scale = requestBody.OutputScale; (var matrix, int rowCount, int colCount) = GenerateMatrix(coord0, coord1); - Mat temp = GenerateTempMat(a1Mat, rowCount, colCount); + Mat temp = GenerateMatCanvas(a1Mat, rowCount, colCount, new Rect()); Parallel.ForEach(matrix, item => { @@ -94,20 +94,42 @@ public class ImageGenerator Coordinate coord1 = new Coordinate(inputs[1]); (var matrix, int rowCount, int colCount) = GenerateMatrix(coord0, coord1); - Mat temp = GenerateTempMat(a1Mat, rowCount, colCount); + + Rect canvasRect = GenerateInitialRectCanvas(a1Mat, rowCount, colCount); + + //Determine cropping region + var globalRoI = GenerateGlobalRoI(requestBody.CropOffset, requestBody.CropSize, canvasRect.Width, + canvasRect.Height); + + Mat canvas = new Mat(globalRoI.Width, globalRoI.Height, a1Mat.Type()); Parallel.ForEach(matrix, item => { - Mat mat = new Mat(item.Path); - if (scale < 1) + try { - mat = mat.Resize(new Size(width, height)); + Mat mat = new Mat(item.Path); + if (scale < 1) + { + mat = mat.Resize(new Size(width, height)); + } + + Rect origin = new Rect((item.Col - 1) * a1Mat.Cols, (item.Row - 1) * a1Mat.Rows, a1Mat.Cols, a1Mat.Rows); + var offset = origin.Location; + var roi = origin.Intersect(globalRoI); + if (roi.Width == 0 || roi.Height == 0) return; + + Rect placement = roi.Subtract(globalRoI.Location); + var localRoi = roi.Subtract(offset); + var subMat = mat.SubMat(localRoi); + subMat.CopyTo(canvas[placement]); + } + catch (Exception e) + { + Console.WriteLine( $"Error {item}, {e.Message}" ); } - Rect rect = new Rect((item.Col - 1) * a1Mat.Cols, (item.Row - 1) * a1Mat.Rows, a1Mat.Cols, a1Mat.Rows); - mat.CopyTo(temp[rect]); }); - var result = temp.ImEncode(); + var result = canvas.ImEncode(); var end = DateTime.Now; var elapsed = end - start; Console.WriteLine($"Elapsed: {elapsed.TotalMilliseconds} ms"); @@ -163,8 +185,29 @@ public class ImageGenerator return (results, rowCount, colCount); } - internal Mat GenerateTempMat(Mat reference, int rowCount, int colCount) + internal Mat GenerateMatCanvas(Mat reference, int rowCount, int colCount, Rect canvas) { - return new Mat(reference.Rows * rowCount, reference.Cols * colCount, reference.Type()); + return new Mat(canvas.Width, canvas.Height, reference.Type()); + // return new Mat(reference.Rows * rowCount - offset.X, reference.Cols * colCount - offset.Y, reference.Type()); + } + + private Rect GenerateInitialRectCanvas(Mat reference, int rowCount, int colCount) + { + int width = reference.Rows * rowCount; + int height = reference.Cols * colCount; + return new Rect(0, 0, width, height); + } + + internal Rect GenerateGlobalRoI(double[] cropOffset, double[] cropSize, int width, int height) + { + int x = (int)(cropOffset[0] * width); + int y = (int)(cropOffset[1] * height); + width = (int)(cropSize[0] * width); + height = (int)(cropSize[1] * height); + + Point location = new Point(x, y); + Size size = new Size(width, height); + Rect cropRegion = new Rect( location, size); + return cropRegion; } } \ No newline at end of file diff --git a/WebApp/RequestBody.cs b/WebApp/RequestBody.cs index 7421f68..9a821fa 100644 --- a/WebApp/RequestBody.cs +++ b/WebApp/RequestBody.cs @@ -5,5 +5,9 @@ namespace WebApp; public record struct RequestBody( [property: JsonPropertyName("canvas_rect")] string CanvasRect, + [property: JsonPropertyName("crop_offset")] + double[] CropOffset, + [property: JsonPropertyName("crop_size")] + double[] CropSize, [property: JsonPropertyName("output_scale")] double OutputScale ); \ No newline at end of file