다음을 통해 공유


Azure Functions: Uploading Images to Storage Blobs

Introduction

There are various ways to do it, but we  have picked up a common scenario where we have an Image on my Local Server and have to Push it into a Blob.

Upload Images Using Stream

Using the HTTP Triggered C# Function where we will send the Request in Json using Path Variable.

Function Looks Like below

public static class JpegStream
 {
 [FunctionName("JpegStream")]
 public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
 {
 log.Info("C# HTTP trigger function processed a request.");
 
 string name;
 
 // Get request body
 dynamic data = await req.Content.ReadAsAsync<object>();
 
 // Set name to query string or body data
 name =  data?.path;
 
 Image img = Image.FromFile(name);
 byte[] arr;
 using (MemoryStream ms = new MemoryStream())
 {
 img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
 arr = ms.GetBuffer();
 
 string storageConnectionString = System.Environment.GetEnvironmentVariable("StorageConnection");
 CloudStorageAccount storageAccount;
 if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
 {
 // Create the CloudBlobClient that represents the Blob storage endpoint for the storage account.
 CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
 
 CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("ContainerName");
 await cloudBlobContainer.CreateIfNotExistsAsync();
 
 CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference("Image1.jpeg");
 cloudBlockBlob.Properties.ContentType = "image\\jpeg";
  
 ms.Seek(0, SeekOrigin.Begin);
 cloudBlockBlob.UploadFromStream(ms);
 }
 }
  
 
 return name == null
 ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a Path  in the request body")
 : req.CreateResponse(HttpStatusCode.OK, "Uploaded to Storage Blob" );
 }
 }

Getting the Storage Connection from the local.settings.json. if we want to Upload the image based on whether the Name already Exists or not, we can just modify the Code Like below

try {
 cloudBlockBlob.UploadFromStream(ms, accessCondition: AccessCondition.GenerateIfNoneMatchCondition("*"));
} catch (StorageException ex) {
 if (ex.RequestInformation.HttpStatusCode == (int)System.Net.HttpStatusCode.Conflict)
 // Handle duplicate blob condition
 }

Upload Images using Byte Array

As explained above Scenario is the same but using the Byte Array to Upload it Code Looks Like below.

[FunctionName("JpegStream")]
 public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
 {
 log.Info("C# HTTP trigger function processed a request.");
 
 string name;
 
 // Get request body
 dynamic data = await req.Content.ReadAsAsync<object>();
 
 // Set name to query string or body data
 name =  data?.path;
 
 Image img = Image.FromFile(name);
 byte[] arr;
 using (MemoryStream ms = new MemoryStream())
 {
 img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
 arr = ms.GetBuffer();
 
 string storageConnectionString = System.Environment.GetEnvironmentVariable("pass");
 CloudStorageAccount storageAccount;
 if (CloudStorageAccount.TryParse(storageConnectionString, out storageAccount))
 {
 // Create the CloudBlobClient that represents the Blob storage endpoint for the storage account.
 CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
 
 CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("fnct");
 await cloudBlobContainer.CreateIfNotExistsAsync();
 
 CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference("sdf.jpeg");
 cloudBlockBlob.Properties.ContentType = "image\\jpeg";
  
 try
 {
 cloudBlockBlob.UploadFromByteArray(arr, 0, arr.Length, accessCondition: AccessCondition.GenerateIfNoneMatchCondition("*"));
 }
 catch (StorageException ex)
 {
 if (ex.RequestInformation.HttpStatusCode == (int)System.Net.HttpStatusCode.Conflict)
 return req.CreateResponse(HttpStatusCode.BadRequest, "file might be already present");
 
 
 }
 }
 }
  
 
 return name == null
 ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a Path  in the request body")
 : req.CreateResponse(HttpStatusCode.OK, "Uploaded to Storage Blob" );
 }
 }

I have added the Exception Condition In the above code so it will Upload only when the blob doesn't contain the name in it.

If we are  downloading the data from web client library, we  can create the Byte array Like below and then we can Upload it to the Blob.

byte[] imageData = null;
using (var wc = new System.Net.WebClient())
{
imageData = wc.DownloadData(myQueueItem);
}

Upload Images using File

In a similar way we can Upload the Image by modifying line of Code like below using File

cloudBlockBlob.UploadFromFile(name);

Request

We can use the Request like below to Test the above Functions

{

  "path":"C:\Pics\IMG_0361 (1).jpg"

}

Hint

Make sure you have installed the WindowsAzure.Storage Nuget Package to utilize these Functions and then you we test all the above code.