Martin Kearn
Martin Kearn

Reputation: 2317

My Azure Storage output blob never shows up

I'm trying to build a simple Azure Function that is based on the ImageResizer example, but uses the Microsoft Cognitive Server Computer Vision API to do the resize.

I have working code for the Computer Vision API which I have ported into the Azure function.

It all seems to work ok (no errors) but my output blob never gets saved or shows up in the storage container. Not sure what I'm doing wrong as there are no errors to work with.

My CSX (C# function code) is as follows

using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;

public static void Run(Stream original, Stream thumb, TraceWriter log)
{
    //log.Verbose($"C# Blob trigger function processed: {myBlob}. Dimensions");
    string _apiKey = "PutYourComputerVisionApiKeyHere";
    string _apiUrlBase = "https://api.projectoxford.ai/vision/v1.0/generateThumbnail";
    string width = "100";
    string height = "100";
    bool smartcropping = true;

    using (var httpClient = new HttpClient())
    {
        //setup HttpClient
        httpClient.BaseAddress = new Uri(_apiUrlBase);
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", _apiKey);

        //setup data object
        HttpContent content = new StreamContent(original);
        content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/octet-stream");

        // Request parameters
        var uri = $"{_apiUrlBase}?width={width}&height={height}&smartCropping={smartcropping}";

        //make request
        var response = httpClient.PostAsync(uri, content).Result;

        //log result
        log.Verbose($"Response: IsSucess={response.IsSuccessStatusCode}, Status={response.ReasonPhrase}");

        //read response and write to output stream
        thumb = new MemoryStream(response.Content.ReadAsByteArrayAsync().Result);
    }
}

My function json is as follows

{
  "bindings": [
    {
      "path": "originals/{name}",
      "connection": "thumbnailgenstorage_STORAGE",
      "name": "original",
      "type": "blobTrigger",
      "direction": "in"
    },
    {
      "path": "thumbs/%rand-guid%",
      "connection": "thumbnailgenstorage_STORAGE",
      "type": "blob",
      "name": "thumb",
      "direction": "out"
    }
  ],
  "disabled": false
}

My Azure storage account is called 'thumbnailgenstorage' and it has two containers named 'originals' and 'thumbs'. The storage account key is KGdcO+hjvARQvSwd2rfmdc+rrAsK0tA5xpE4RVNmXZgExCE+Cyk4q0nSiulDwvRHrSAkYjyjVezwdaeLCIb53g==.

I'm perfectly happy for people to use my keys to help me figure this out! :)

Upvotes: 0

Views: 646

Answers (1)

Martin Kearn
Martin Kearn

Reputation: 2317

I got this working now. I was writing the output stream incorrectly.

This solution is an Azure function which triggers on the arrival of a blob in an Azure Blob Storage container called 'Originals', then uses the Computer Vision API to smartly resize the image and store in in a different blob container called 'Thumbs'.

Here is the working CSX (c# script):

using System;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;

public static void Run(Stream original, Stream thumb, TraceWriter log)
{
    int width = 320;
    int height = 320;
    bool smartCropping = true;
    string _apiKey = "PutYourComputerVisionApiKeyHere";
    string _apiUrlBase = "https://api.projectoxford.ai/vision/v1.0/generateThumbnail";

    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri(_apiUrlBase);
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", _apiKey);
        using (HttpContent content = new StreamContent(original))
        {
            //get response
            content.Headers.ContentType = new MediaTypeWithQualityHeaderValue("application/octet-stream");
            var uri = $"{_apiUrlBase}?width={width}&height={height}&smartCropping={smartCropping.ToString()}";
            var response = httpClient.PostAsync(uri, content).Result;
            var responseBytes = response.Content.ReadAsByteArrayAsync().Result;

            //write to output thumb
            thumb.Write(responseBytes, 0, responseBytes.Length);
        }
    }
}

Here is the integration JSON

{
  "bindings": [
    {
      "path": "originals/{name}",
      "connection": "thumbnailgenstorage_STORAGE",
      "name": "original",
      "type": "blobTrigger",
      "direction": "in"
    },
    {
      "path": "thumbs/{name}",
      "connection": "thumbnailgenstorage_STORAGE",
      "name": "thumb",
      "type": "blob",
      "direction": "out"
    }
  ],
  "disabled": false
}

Upvotes: 2

Related Questions