111 lines
No EOL
3.8 KiB
C#
111 lines
No EOL
3.8 KiB
C#
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<Coordinate> 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<Coordinate> results = new List<Coordinate>(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;
|
|
}
|
|
} |