Capturing and Uploading Images to Azure Blob Storage from Universal Windows Apps

In the previous post, I shared how an Azure function can really take
load off your Rest API or other mechanisms to do some automated action on a new
addition to something like a blob storage.

In the example, we wrote a small
Azure function app that, once stitched in, get triggered on a new upload to a
blob storage. This Azure function uses Azure Cognitive Service to generate a smart
thumbnail and saves it back to another blob storage.

This post is the other part of story and may be considered a
prequel/sequel.

We will see how quickly we can write an app that can upload to an Azure Blob
Storage!


We created a storage account with two blob storage containers named
originals and thumbnails. We will go back to the containers in
the portal click on the … and select properties. In the container property
window, we will find the URL that is needed to access the blob storage.

In the container settings, you will find the access keys; be sure not to
share the access keys!

 

For the demo purpose, I saved the keys in App.xaml

<Application
    x:Class="PicUpload.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PicUpload"
    RequestedTheme="Light">
    <Application.Resources>
        <x:String x:Key="SubscriptionKey">YOUR_COGNITIVE_SERVICE_KEY</x:String>
        <x:String x:Key="BaseURI">https://api.projectoxford.ai/face/v1.0/persongroups</x:String>
        <x:String x:Key="StoragePath">https://function073638f08fcd.blob.core.windows.net/</x:String>
        <x:String x:Key="StorageAccountName">function073638f08fcd</x:String>
        <x:String x:Key="StorageAccountKey">YOUR_STORAGE_ACCOUNT_KEY</x:String>
    </Application.Resources>

</Application>

In the program I initialized variables and objects as

private static readonly string StorageAccountName = Application.Current.Resources["StorageAccountName"].ToString();
private static readonly string StorageAccountKey = Application.Current.Resources["StorageAccountKey"].ToString();
private static readonly StorageCredentials cred = new StorageCredentials(StorageAccountName, StorageAccountKey);

public static readonly string storagePath = Application.Current.Resources["StoragePath"].ToString();
public static readonly CloudBlobContainer blobContainer = new CloudBlobContainer(new Uri(storagePath + "originals"), cred);
public static readonly CloudBlobContainer thumbContainer = new CloudBlobContainer(new Uri(storagePath + "thumbnails"), cred);
        

In the app, I provided two option to pick an image from, either the in-built camera app or the picture gallery

For picture gallery, I used FileOpenPicker in-built control, set its default path to Pictures Library and added the extensions I want to allow. Since the function does not return a file but instead directly uploads to blob, which is an async call, I declared my function as async.

        using Windows.Storage.Streams;
        using Windows.Storage.Pickers;
        private async void btnPickFromFile_Click(object sender, RoutedEventArgs e)
        {
            FileOpenPicker filePicker = new FileOpenPicker();
            filePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
            filePicker.ViewMode = PickerViewMode.Thumbnail;

            filePicker.FileTypeFilter.Clear();
            filePicker.FileTypeFilter.Add(".jpeg"); filePicker.FileTypeFilter.Add(".jpg");
            filePicker.FileTypeFilter.Add(".png"); filePicker.FileTypeFilter.Add(".gif");

            StorageFile file = await filePicker.PickSingleFileAsync();
            if (null != file)
            {
                string blobFileName = await updateToBlob(file);
                AddFaceToPerson(blobFileName);
            }
        }

This is even simpler for the camera app. I just called in the CameraCaptureUI

        using Windows.Storage.Streams;
        using Windows.Media.Capture;
        private async void btnPickFromCamera_Click(object sender, RoutedEventArgs e)
        {
            CameraCaptureUI dialog = new CameraCaptureUI();
            StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);
            string blobFileName = await updateToBlob(file);
            AddFaceToPerson(blobFileName);
        }

Once, I have the image, I can upload to the blob storage as

        using Windows.Storage.Streams;
        private async Task<string> updateToBlob(StorageFile file)
        {
            CloudBlockBlob blob = null;
            string filename = null;
            BitmapImage bitmapImage = new BitmapImage();
            IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);

            if (null != fileStream)
            {
                fileName = System.Guid.NewGuid() + "." + file.Name.Split('.').Last<string>();
                bitmapImage.SetSource(fileStream);
                
                // Show image in a image box - CapturedPhoto
                CapturedPhoto.Source = bitmapImage;
                
                await blobContainer.CreateIfNotExistsAsync();
                blob = blobContainer.GetBlockBlobReference(blobFileName);
                await blob.DeleteIfExistsAsync();
                await blob.UploadFromFileAsync(file);
            }
            return filename;
        }

 


I renamed files to guid.ext so I can save all uploads, otherwise DeleteIfExistsAsync() will overwrite any file with same name in the store. I can now go back to the azure portal and verify my images getting uploaded.

Also, the thumbnails are getting generated. (There is no thumbnail for one of the files because in my Azure function I had named the source as original/{name} instead of originals/{name}. Have corrected it in original post as well)

Now I have a thumbnail getting generated for every image file I upload to the blob storage. In the Function log I can see the function getting fired and its results as

I can write another Azure function that triggers on image addition to thumbnail blob and send it through events or notification hub, I can read text in the image or identify object through Azure cognitive service and send through SMS, etc… Possibilities are enormous!

Advertisements

2 thoughts on “Capturing and Uploading Images to Azure Blob Storage from Universal Windows Apps

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s