Search code examples
c#azure-blob-storageimageresizerazure-webjobssdkazure-functions

Azure Function - Resize image stored in a blob container


I've answered this question related to Azure Webjob and Resizing a image stored as a blob and so I am trying to do the same using a Function App

Each time a new blob is uploaded, I send a a new queue message. My function is triggered by the queue message and bind to the uploaded blob. I also have a second input binding that binds to another CloudBlobContainer to be able to upload new resized images to another blob container.

My function looks like that:

#r "System.Web"
using System.IO;
using System.Web;
using ImageResizer;
using Microsoft.Azure.WebJobs;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

private static readonly int[] Sizes = { 800, 500, 250 };

public static void Run(string filename, Stream blobStream, CloudBlobContainer container, TraceWriter log)
{
    log.Verbose($"C# Queue trigger function processed: {filename}");
    // Extract the filename  and the file extension
    var name = Path.GetFileNameWithoutExtension(filename);
    var ext = Path.GetExtension(filename);

    // Get the mime type to set the content type
    var mimeType = MimeMapping.GetMimeMapping(filename);

    foreach (var width in Sizes)
    {
        // Set the position of the input stream to the beginning.
        blobStream.Seek(0, SeekOrigin.Begin);

        // Get the output stream
        var outputStream = new MemoryStream();
        ResizeImage(blobStream, outputStream, width);

        // Get the blob reference
        CloudBlockBlob blob = container.GetBlockBlobReference($"{name}-w{width}.{ext}");

        // Set the position of the output stream to the beginning.
        outputStream.Seek(0, SeekOrigin.Begin);
        blob.UploadFromStream(outputStream);

        // Update the content type =>  don't know if required
        blob.Properties.ContentType = mimeType;
        blob.SetProperties();
    }               
}

private static void ResizeImage(Stream input, Stream output, int width)
{
    var instructions = new Instructions
    {
        Width = width,
        Mode = FitMode.Carve,
        Scale = ScaleMode.Both
    };
    var imageJob = new ImageJob(input, output, instructions);

    // Do not dispose the source object
    imageJob.DisposeSourceObject = false;
    imageJob.Build();
}

The associated function.json file:

{
"bindings": [
  {
    "queueName": "newfileuploaded",
    "connection": "crazytunastorageaccount_STORAGE",
    "name": "filename",
    "type": "queueTrigger",
    "direction": "in"
  },
  {
    "path": "input-images/{queueTrigger}",
    "connection": "crazytunastorageaccount_STORAGE",
    "name": "blobStream",
    "type": "blob",
    "direction": "in"
  },
  {
    "name": "container",
    "type": "blob",
    "path": "output-images",
    "connection": "crazytunastorageaccount_STORAGE",
    "direction": "in"
  }
],
"disabled": false
}

And the project.json file:

{
"frameworks": {
  "net46":{
    "dependencies": {
      "ImageResizer": "4.0.5",
      "WindowsAzure.Storage": "4.3.0"
    }
  }
 }
}

Now when I compiled the function, I always got this error:

Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.ResizeBlobImage'. Microsoft.Azure.WebJobs.Host: Can't bind Blob to type 'Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer'.

Is this type supported for the moment ?


Solution

  • Yes CloudBlobContainer is supported. I tried a quick sample myself now, and the below function works for me, using the same binding metadata you showed above. I'm also using the same version of the WebJobs SDK in project.json.

    using System;
    using Microsoft.WindowsAzure.Storage.Blob;
    
    public static void Run(
        string blobTrigger, Stream inputBlob, Stream outputBlob,
        CloudBlobContainer container, TraceWriter log)
    {
        log.Info($"Container name: {container.Name}");
    
        log.Info($"C# Blob trigger function processed {blobTrigger}");
        inputBlob.CopyTo(outputBlob);        
    }
    

    Not sure why this wasn't working for you. I have seen some Portal glitches from time to time (bugs we're fixing) that sometimes cause issues.