using StitcherApi.Models; using StitcherApi.Services.Utilities; namespace StitcherApi.Services; public class ImageService : IImageService { private readonly ILogger _logger; private readonly StitchProcessor _stitchProcessor; public ImageService(IConfiguration config, ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger(); string assetPath = config["AssetPath"] ?? throw new InvalidOperationException("AssetPath not configured."); _stitchProcessor = new StitchProcessor( assetPath, loggerFactory.CreateLogger() ); } public async Task GenerateImageAsync(GenerateImageRequest request) { _logger.LogInformation("Processing request with the fast processor..."); (int minRow, int minCol, int maxRow, int maxCol) = CoordinateParser.ParseCanvasRect( request.CanvasRect ); StitchRequest stitchRequest = CreateStitchRequest(request, minRow, minCol, maxRow, maxCol); return await _stitchProcessor.ProcessAsync(stitchRequest); } private StitchRequest CreateStitchRequest( GenerateImageRequest request, int minRow, int minCol, int maxRow, int maxCol ) { const int TILE_SIZE = 720; int stitchedCanvasWidth = (maxCol - minCol + 1) * TILE_SIZE; int stitchedCanvasHeight = (maxRow - minRow + 1) * TILE_SIZE; int cropX = (int)(request.CropOffset[0] * stitchedCanvasWidth); int cropY = (int)(request.CropOffset[1] * stitchedCanvasHeight); int cropW = (int)(request.CropSize[0] * stitchedCanvasWidth); int cropH = (int)(request.CropSize[1] * stitchedCanvasHeight); int startTileCol = minCol + cropX / TILE_SIZE; int endTileCol = minCol + (cropX + cropW - 1) / TILE_SIZE; int startTileRow = minRow + cropY / TILE_SIZE; int endTileRow = minRow + (cropY + cropH - 1) / TILE_SIZE; return new StitchRequest( minRow, minCol, startTileRow, startTileCol, endTileRow, endTileCol, cropX, cropY, cropW, cropH, request.OutputScale ); } }