using System.Collections.Concurrent; using OpenCvSharp; namespace WebApp; public class ImageGenerator { private const string PATH = "D:/tiles1705/"; public byte[] GenerateImage(RequestBody requestBody) { var start = DateTime.Now; string[] inputs = requestBody.CanvasRect.Split(":"); Coordinate coord0 = new Coordinate(inputs[0]); Coordinate coord1 = new Coordinate(inputs[1]); (var matrix, _, _) = GenerateDict(coord0, coord1); ConcurrentDictionary rows = new(); Parallel.ForEach(matrix, pair => { Mat row = new Mat(); List mats = new(); foreach (var coord in pair.Value) { string fileName = PATH + coord.Name + ".png"; mats.Add(new Mat( fileName ) ); } Cv2.HConcat(mats, row); rows[pair.Key] = row; }); Mat output = new Mat(); Cv2.VConcat(rows.Values, output); var result = output.ImEncode(); var end = DateTime.Now; var elapsed = end - start; Console.WriteLine($"Elapsed: {elapsed.TotalMilliseconds} ms"); return result; } public byte[] GenerateImage2(RequestBody requestBody) { var start = DateTime.Now; Coordinate a1 = new Coordinate("A1"); Mat a1Mat = new Mat(a1.Path); string[] inputs = requestBody.CanvasRect.Split(":"); Coordinate coord0 = new Coordinate(inputs[0]); Coordinate coord1 = new Coordinate(inputs[1]); double scale = requestBody.OutputScale; (var matrix, int rowCount, int colCount) = GenerateMatrix(coord0, coord1); Mat temp = GenerateTempMat(a1Mat, rowCount, colCount); Parallel.ForEach(matrix, item => { Mat mat = new Mat(item.Path); Rect rect = new Rect((item.Col - 1) * a1Mat.Cols, (item.Row - 1) * a1Mat.Rows, a1Mat.Cols, a1Mat.Rows); mat.CopyTo(temp[rect]); }); double newWidth = temp.Width * scale; double newHeight = temp.Height * scale; temp.Resize(new Size(newWidth, newHeight)); var result = temp.ImEncode(); var end = DateTime.Now; var elapsed = end - start; Console.WriteLine($"Elapsed: {elapsed.TotalMilliseconds} ms"); return result; } internal (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); } internal (ConcurrentDictionary> Matrix, int RowCount, int ColCount) GenerateDict(Coordinate coordinate1, Coordinate coordinate2) { ConcurrentDictionary> results = new(); 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; for (int i = 0; i < rowCount; i++) { List result = new(); for (int j = 0; j < colCount; j++) { int row = minRow + i; int col = minCol + j; result.Add(new Coordinate(row, col)); } results[i] = result; } return (results, rowCount, colCount); } internal Mat GenerateTempMat(Mat reference, int rowCount, int colCount) { return new Mat(reference.Rows * rowCount, reference.Cols * colCount, reference.Type()); } }