Azure Functions – Resize Images Uploaded to Blob Storage

Scenario

I have been capturing images with my power App, which are uploaded to a Blob Storage. My power App uses the build in phone camera to capture images, hence each image size is more than 2 MB.

I use these images in one of my reports generated periodically via logic app (also converted to pdf). Sometimes there can be more than 40 images in my report and as you can imagine the system takes a lot of time to first download the images, because of the size, and my report generation fails.

Now, to avoid this situation, I can do couple of things:

  • Setup my camera to use lowest settings for image size. However, with today’s devices even the lowest settings generate images in MBs. Also, it is not possible all the time. Try setting that as best practice for your customers!
  • I can use the Camera App (provided by the Power App), which usually captures images in KBs. However, there are various limitations like, I can’t use (at least for now) Flash, zoom in, zoom out and many other features that my device provides.

Solution

So, the most appropriate solution would be to create a function that monitors my Blob Storage, where my images are uploaded and whenever there is an image which exceeds certain size, I would like the function to resize the image and store it in the same place.

Credits to original post.

Prerequisite

To replicate this scenario, we will create a Blob Storage to store our images and use Microsoft Azure Storage Explorer.

Blob Storage

Create a Blob Storage:

  • Specify a unique Name
  • Select Account Kind
  • Select Location
  • Select Replication
  • Select Subscription
  • Create a new Resource Group or use existing
  • Click Create.

Within the storage, use the Blob Service and create a Container where the images will be stored.

Microsoft Azure Storage Explorer

Download and Install Microsoft Azure Storage Explorer and configure it to access the Blob Storage. We will be using it to simulate upload of sample image.

Create a Function App Service

  • Use Function App to create a new function:
    • Specify unique App Name
    • Select Subscription
    • Create a new Resource Group or use existing
    • Select Hosting Plan
    • Select Location
    • Create a new Storage or use existing
    • Click Create

Create a Function Trigger

  • Create a new function trigger based on Blob Trigger template using C#
  • Specify Name of the function trigger
  • Specify the Path, this is the path to the source of the images
  • Select the Storage Account Connection
  • Click Create

NOTE: If you do not see your storage account connection, click New.

The portal will create a binding for your script that will allow you to process files created at the path specified.

The connection string for your storage account will automatically be created and added to your Function App. To see how this is connected, inspect the function.json file in your function through the View Files tool pane.

You can also click on the Integrate menu and check the settings:

Add New Output Binding

We need to add another parameter binding, this time for output, so that we can save out the resized image back to Azure Blob Storage (same location in this example).

  • Click on the Integrate menu
  • Click New Output to create output binding.

  • Select Azure Blob Storage

  • Specify Blob Parameter Name
  • Specify Path (in this example it is the same path where we need to save the output)
  • Select Storage Account Connection

Note: The path, where we are reusing the {imageName} parameter. This was the name of the file coming into our function, and we will save it out as the same filename in the same location, essentially replacing the original file. If you want you can specify different path to store the resized file.

Add Files to Make the Function Work

Project.json

  • Under View Files button add a new file called project.json and add the following code. This is how the Function Apps use to restore packages from NuGet.
{

“frameworks”: {

“net46”:{

“dependencies”: {

“ImageResizer”: “4.0.4”

}

}

}

}

  • Save the file.

Run.csx

  • Navigate to run.csx, the script file for the endpoint.
  • Use the following code. We are using the ImageResizer library to execute a resize operation with one stream as the source and the other as the output.
#r “System.Drawing”

using ImageResizer;

using System.Drawing;

using System.Drawing.Imaging;

public static void Run(Stream inputImage, string imageName, Stream resizedImage, TraceWriter log)

{

log.Info($”C# Blob trigger function Processed blob\n Name:{imageName} \n Size: {inputImage.Length} Bytes”);

var settings = new ImageResizer.ResizeSettings{

MaxWidth = 400

};

if(inputImage.Length > 500000){

ImageResizer.ImageBuilder.Current.Build(inputImage, resizedImage, settings);

}

else

{

log.Info($”Name:{imageName} \n Size: {inputImage.Length} Bytes is too small ignoring file”);

}

}

  • Save the file.

Check the log to see if the compilation was a success.

Test the Solution

  • In this example we are uploading an image file of size around 3.71 MB.

  • Using the Azure Storage Explorer upload the sample image. Use the Upload button. Note the size.

  • The function sees that an image of larger size has been uploaded and runs the logic to resize the image.
  • Refresh the Azure Storage Explorer after few seconds and check the size of the image, it would have been reduced as per the logic.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.