using OpenCvSharp; namespace WebApp; public class ImageGenerator { public byte[] GenerateImage3(RequestBody requestBody) { var start = DateTime.Now; string[] inputs = requestBody.CanvasRect.Split(":"); double scale = requestBody.OutputScale; Coordinate a1 = new Coordinate("A1"); Mat a1Mat = new Mat(a1.Path); int width = a1Mat.Width; int height = a1Mat.Height; if (scale < 1) { width = (int)(width * scale); height = (int)(height * scale); a1Mat = a1Mat.Resize(new Size(width, height)); } Coordinate coord0 = new Coordinate(inputs[0]); Coordinate coord1 = new Coordinate(inputs[1]); (var matrix, int rowCount, int colCount) = GenerateMatrix(coord0, coord1); 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.Height, globalRoI.Width, a1Mat.Type()); Parallel.ForEach(matrix, item => { try { 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}" ); } }); var result = canvas.ImEncode(); var end = DateTime.Now; var elapsed = end - start; Console.WriteLine($"Elapsed: {elapsed.TotalMilliseconds} ms"); return result; } private (List Matrix, int RowCount, int ColCount) GenerateMatrix(Coordinate coordinate1, Coordinate coordinate2) { int minRow = Math.Min(coordinate1.Row, coordinate2.Row); int maxRow = Math.Max(coordinate1.Row, coordinate2.Row); int minCol = Math.Min(coordinate1.Col, coordinate2.Col); int maxCol = Math.Max(coordinate1.Col, coordinate2.Col); int rowCount = maxRow - minRow + 1; int colCount = maxCol - minCol + 1; // Initialize collections List results = new List(rowCount*colCount); for (int i = 1; i <= rowCount; i++) { for (int j = 1; j <= colCount; j++) { results.Add(new Coordinate(i,j)); } } return (results, rowCount, colCount); } private Rect GenerateInitialRectCanvas(Mat reference, int rowCount, int colCount) { int width = reference.Width * colCount; int height = reference.Height * rowCount; return new Rect(0, 0, width, height); } private Rect GenerateGlobalRoI(float[] cropOffset, float[] 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; } }