Part 1 - Create an AWS Lambda Project

Follow the steps below to create and customize an ASP.NET Web API Project in Visual Studio.

1. In Visual Studio, use File -> New -> Project to open the New Project dialog.

2. 2. Under the Web project node, select AWS Lambda and the “AWS Lambda Project with Tests (.Net Core)” template, type Resize-Lambda-Userid as the name for your project, then click the OK button

3. In the next dialog, select the “API” blueprint, and select “Simple S3 Function”, then click the Finish button to generate the project.

4. Right-click on the solution that you have create and select Manage NuGet Packages:

Note: In this Lab we will use an open-source image library to resize the picture as .net core doesn’t have any built-in classes to work with images at this time.

a. For this Lab we will install an open-source third-party library called ImageSharp that is only available at the NuGet pre-release. Please, search SixLabors selecting the pre-release check-box.

b. Select and install the SixLabors.ImageSharp and SixLabors.ImageSharp.Drawing packages.

// Copyright <YEAR> Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
public async Task<string> FunctionHandler(S3Event evnt, ILambdaContext context)
        {
            string[] fileExtentions = new string[] { ".jpg", ".jpeg" };
            var s3Event = evnt.Records?[0].S3;
            if(s3Event == null)
            {
                return null;
            }

            try
            {
                foreach (var record in evnt.Records)
                {
                    LambdaLogger.Log("----> File: " + record.S3.Object.Key);
                    if (!fileExtentions.Contains(Path.GetExtension(record.S3.Object.Key).ToLower()))
                    {
                        LambdaLogger.Log("File Extention is not supported - " + s3Event.Object.Key);
                        continue;
                    }
                    string suffix = Path.GetExtension(record.S3.Object.Key).ToLower();
                    Stream imageStream = new MemoryStream();
                    using (var objectResponse = await S3Client.GetObjectAsync(record.S3.Bucket.Name, record.S3.Object.Key))
                    using (Stream responseStream = objectResponse.ResponseStream)
                    {
                        using (Image<Rgba32> image = Image.Load(responseStream)) 
                        {                            
                            image.Mutate(ctx => ctx.Resize(image.Width / 4, image.Height / 4));
                            image.Save(imageStream, new JpegEncoder());
                            imageStream.Seek(0, SeekOrigin.Begin);
                        }
                    }
                    // Creating a new S3 ObjectKey for the resized objects
                    string resizedObjectKey = null;
                    int endSlash = record.S3.Object.Key.ToLower().LastIndexOf("/");
                    if (endSlash > 0)
                    {
                        string S3ObjectName = record.S3.Object.Key.ToLower().Substring(endSlash+1);
                        int beginSlash = 0;
                        if (endSlash > 0)
                        {
                            beginSlash = record.S3.Object.Key.ToLower().Substring(0, endSlash - 1).LastIndexOf("/");
                            if (beginSlash > 0)
                            {
                                resizedObjectKey = record.S3.Object.Key.ToLower().Substring(0, beginSlash) + "resized-images/" + S3ObjectName;
                            }
                            else
                            {
                                resizedObjectKey = "resized-images/" + S3ObjectName;
                            }
                        }
                    }
                    else
                    {
                        resizedObjectKey = "resized-images/" + record.S3.Object.Key.ToLower();
                    }

                    LambdaLogger.Log("----> Resized filed Key: " + resizedObjectKey);

                    await S3Client.PutObjectAsync(new PutObjectRequest
                    {
                        BucketName = record.S3.Bucket.Name,
                        Key = resizedObjectKey,
                        InputStream = imageStream
                    });
                }

                LambdaLogger.Log("Processed " + evnt.Records.Count.ToString());

                return null;
            }
            catch(Exception e)
            {
                context.Logger.LogLine($"Error getting object {s3Event.Object.Key} from bucket {s3Event.Bucket.Name}. Make sure they exist and your bucket is in the same region as this function.");
                context.Logger.LogLine(e.Message);
                context.Logger.LogLine(e.StackTrace);
                throw;
            }
        }

6. Add the following Using statements to the top of the Function.cs file.

using System.IO;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.PixelFormats;
using Amazon.S3.Model;
using SixLabors.ImageSharp.Formats.Jpeg;