Пример #1
0
        public async Task <State> FunctionHandler(State state, ILambdaContext context)
        {
            var tmpPath = Path.Combine(Path.GetTempPath(), Path.GetFileName(state.SourceKey));

            try
            {
                context.Logger.LogLine("Saving image to tmp");
                using (var response = await S3Client.GetObjectAsync(state.Bucket, state.SourceKey))
                {
                    await response.WriteResponseStreamToFileAsync(tmpPath, false, default(CancellationToken));
                }

                var mosaicLayoutInfo = MosaicLayoutInfoManager.Create();
                state.MosaicLayoutInfoKey = mosaicLayoutInfo.Key;

                context.Logger.LogLine($"Loading image {tmpPath}. File size {new FileInfo(tmpPath).Length}");
                using (var sourceImage = Image.Load(tmpPath))
                {
                    state.OriginalImagePixelCount = sourceImage.Width * sourceImage.Height;
                    if (state.OriginalImagePixelCount < State.SMALL_IMAGE_SIZE)
                    {
                        state.PixelBlock = 3;
                    }
                    else if (state.OriginalImagePixelCount < State.MEDIUM_IMAGE_SIZE)
                    {
                        state.PixelBlock = 5;
                    }
                    else if (state.OriginalImagePixelCount < State.MAX_IMAGE_SIZE)
                    {
                        state.PixelBlock = 10;
                    }
                    else
                    {
                        throw new Exception("Image too large to make a mosaic");
                    }

                    mosaicLayoutInfo.ColorMap = CreateMap(state, sourceImage);
                }

                context.Logger.LogLine($"Color map created: {mosaicLayoutInfo.ColorMap.GetLength(0)}x{mosaicLayoutInfo.ColorMap.GetLength(1)}");

                await MosaicLayoutInfoManager.Save(S3Client, state.Bucket, mosaicLayoutInfo);

                context.Logger.LogLine($"Saving mosaic layout info to {mosaicLayoutInfo.Key}");

                return(state);
            }
            finally
            {
                if (File.Exists(tmpPath))
                {
                    File.Delete(tmpPath);
                }
            }
        }
Пример #2
0
        public async Task <State> FunctionHandler(State state, ILambdaContext context)
        {
            if (Directory.Exists(this.TileImageCacheDirectory))
            {
                Directory.Delete(this.TileImageCacheDirectory, true);
            }

            Directory.CreateDirectory(this.TileImageCacheDirectory);

            context.Logger.LogLine("Loading mosaic layout info");
            var mosaicLayoutInfo =
                await MosaicLayoutInfoManager.Load(this.S3Client, state.Bucket, state.MosaicLayoutInfoKey);

            var width  = mosaicLayoutInfo.ColorMap.GetLength(0) * state.TileSize;
            var height = mosaicLayoutInfo.ColorMap.GetLength(1) * state.TileSize;

            context.Logger.LogLine($"Creating pixel data array {width}x{height}");
            var pixalData = new Rgba32[width * height];

            for (int i = 0; i < pixalData.Length; i++)
            {
                pixalData[i] = Rgba32.Black;
            }

            context.Logger.LogLine($"Creating blank image");
            using (var rawImage = Image.LoadPixelData(pixalData, width, height))
            {
                context.Logger.LogLine($"Created blank image");
                for (int x = 0; x < mosaicLayoutInfo.ColorMap.GetLength(0); x++)
                {
                    int xoffset = x * state.TileSize;
                    context.Logger.LogLine($"Processing row {x}");
                    for (int y = 0; y < mosaicLayoutInfo.ColorMap.GetLength(1); y++)
                    {
                        int yoffset = y * state.TileSize;
                        var tileId  = mosaicLayoutInfo.TileMap[x, y];
                        var tileKey = mosaicLayoutInfo.IdToTileKey[tileId];

                        using (var tileImage = await LoadTile(state.Bucket, tileKey, context))
                        {
                            for (int x1 = 0; x1 < state.TileSize; x1++)
                            {
                                for (int y1 = 0; y1 < state.TileSize; y1++)
                                {
                                    rawImage[x1 + xoffset, y1 + yoffset] = tileImage[x1, y1];
                                }
                            }
                        }
                    }
                }

                // Write full mosaic to S3
                {
                    var finalOutputStream = new MemoryStream();
                    rawImage.Save(finalOutputStream, new SixLabors.ImageSharp.Formats.Jpeg.JpegEncoder());
                    finalOutputStream.Position = 0;

                    var destinationKey =
                        S3KeyManager.DetermineS3Key(state.UserId, state.MosaicId, S3KeyManager.ImageType.FullMosaic);
                    context.Logger.LogLine(
                        $"Saving full mosaic to {destinationKey} with size {finalOutputStream.Length}");
                    await this.S3Client.PutObjectAsync(new PutObjectRequest
                    {
                        BucketName  = state.Bucket,
                        Key         = destinationKey,
                        InputStream = finalOutputStream
                    });
                }

                // Write web size mosaic to S3
                await SaveResize(state, rawImage, Constants.IMAGE_WEB_WIDTH, Constants.IMAGE_WEB_HEIGHT,
                                 S3KeyManager.DetermineS3Key(state.UserId, state.MosaicId, S3KeyManager.ImageType.WebMosaic),
                                 context);

                // Write thumbnail mosaic to S3
                await SaveResize(state, rawImage, Constants.IMAGE_THUMBNAIL_WIDTH, Constants.IMAGE_THUMBNAIL_HEIGHT,
                                 S3KeyManager.DetermineS3Key(state.UserId, state.MosaicId, S3KeyManager.ImageType.ThumbnailMosaic),
                                 context);

                return(state);
            }
        }