Generate an image thumbnail using Azure Functions

Generate an image thumbnail using Azure Functions

What is Azure Blob Storage?

According to the official?MS Docs?(Introduction to Blob (object) storage - Azure Storage | Microsoft Docs)?Blob storage is Microsoft’s cloud storage which can be used to store large volumes of unstructured data like images, audio, video and others.


What are Azure Functions?

According to the official?MS Docs?(Azure Functions Overview | Microsoft Docs)?an Azure Function is a serverless solution that allows you to write less code, maintain less infrastructure, and save on costs.??

Some of the benefits of using Azure Functions are:?

  • They are scalable?
  • They are fast to execute?
  • They are serverless

? If you want to find out more about Azure Functions, I cover other information and usage for them in my other article:

Consume a batch of messages in an Azure Function from an Azure Service Bus

and

Build a serverless API using an Azure Function that reads and writes data to an Azure Cosmos DB with little to no code


Setting up the Storage Account and Containers

I have already created a storage account named 'ilievsa'.

In it, I created two containers. The first container named 'profileimages' will store the profile images for the users, while the second one named 'thumbnailimages' will store the thumbnail images generated from the profile images.

No alt text provided for this image

Now let’s create and implement the two Azure Functions we will use.


Project structure

No alt text provided for this image


Implementing the Azure Functions

First, we will create an Azure Function which will use an HTTP trigger. It will receive a single file from an HTTP POST request and upload that file to the 'profileimages' container.?

Let’s take a look at the code implementation for the function:

using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;


namespace ImageUploader
{
? ? public static class ImageUploader
? ? {
? ? ? ? [FunctionName("upload")]
? ? ? ? public static async Task<IActionResult> Run(
? ? ? ? ? ? [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
? ? ? ? ? ? [Blob("profileimages", Connection = "BlobStorageConnection")] CloudBlobContainer outputContainer)
? ? ? ? {
? ? ? ? ? ? byte[] imageBytes;


? ? ? ? ? ? var file = req.Form.Files[0];


? ? ? ? ? ? using (var ms = new MemoryStream())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? file.CopyTo(ms);
? ? ? ? ? ? ? ? imageBytes = ms.ToArray();
? ? ? ? ? ? }


? ? ? ? ? ? var cloudBlockBlob = outputContainer.GetBlockBlobReference(file.FileName);


? ? ? ? ? ? using (MemoryStream stream = new MemoryStream(imageBytes, 0, imageBytes.Length))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? await cloudBlockBlob.UploadFromStreamAsync(stream);
? ? ? ? ? ? }


? ? ? ? ? ? return new OkResult();
? ? ? ? }
? ? }
}        

Next, let’s create the Azure Function which will use the Blob Storage trigger and make the thumbnail image. This function will take the image we just uploaded, create a thumbnail from it and upload that new thumbnail image to the 'thumbnailimages' container.

For resizing of the image, we will use the following NuGet package: System.Drawing.Common.

Let’s take a look at the code implementation for the function:

using System.Drawing;
using System.IO;
using Microsoft.Azure.WebJobs;


namespace ThumbnailImageGenerator
{
? ? public class ThumbnailGenerator
? ? {
? ? ? ? [FunctionName("generate")]
? ? ? ? public static void Run([BlobTrigger("profileimages/{name}", Connection = "BlobStorageConnection")] Stream image, [Blob("thumbnailimages/thumbnail-{name}", FileAccess.Write, Connection = "BlobStorageConnection")] Stream thumbnail)
? ? ? ? {
? ? ? ? ? ? byte[] imageBytes;


? ? ? ? ? ? byte[] buffer = new byte[16 * 1024];


? ? ? ? ? ? using (MemoryStream stream = new MemoryStream())
? ? ? ? ? ? {
? ? ? ? ? ? ? ? int read;
? ? ? ? ? ? ? ? while ((read = image.Read(buffer, 0, buffer.Length)) > 0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? stream.Write(buffer, 0, read);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? imageBytes = stream.ToArray();
? ? ? ? ? ? }


? ? ? ? ? ? using (MemoryStream stream = new MemoryStream(imageBytes, 0, imageBytes.Length))
? ? ? ? ? ? {
? ? ? ? ? ? ? ? using (Image imageFromStream = Image.FromStream(stream))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? int height = 100;
? ? ? ? ? ? ? ? ? ? int width = 100;


? ? ? ? ? ? ? ? ? ? using (Bitmap bitmap = new Bitmap(imageFromStream, new Size(width, height)))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? bitmap.Save(thumbnail, System.Drawing.Imaging.ImageFormat.Jpeg);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}        

Let's test our implementation. Start both of the Azure Function projects.

No alt text provided for this image

Using Postman let’s make an HTTP POST request with a file added to the first Azure Function.

No alt text provided for this image

Observe that the first Azure Function completes successfully.

Then, after a short time, we can see that the second Azure Function was triggered as well, which also executed successfully.

No alt text provided for this image

Let’s take a look at what we have in our containers now.

In the 'profileimages' container we can see that our profile image was uploaded as expected.

No alt text provided for this image

Next, open the 'thumbnailimage' container. Inside we will see our newly generated thumbnail image.

No alt text provided for this image

If we download, open and compare both of the images, we can see the difference in sizes.

No alt text provided for this image

Perfect. We have successfully uploaded a profile image using an Azure Function with an HTTP trigger to a container. Then, it triggered an Azure Function with a blob storage trigger to generate a thumbnail image and upload it to another container.

Thanks for sticking to the end of another article from?"Iliev Talks Tech".?#ilievtalkstech

The full, more detailed implementation of this example can be found on my GitHub repository on the following link:

DimitarIliev/thumbnail-generator (github.com)

Next steps:

要查看或添加评论,请登录

Dimitar Iliev ??的更多文章

社区洞察

其他会员也浏览了