Uploading Image Blobs–Stream vs Byte Array (Year of Azure Week 4)
July 28, 2011 10 Comments
Ok, I promised you with when I started some of this Year of Azure project that some of these would be short. Its been a busy week so I’m going to give you a quickly based on a question posted on MSDN Azure forums.
The question centered around getting the following code snippit to work (I’ve paraphrased this a bit).
- MemoryStream streams = new MemoryStream();
- // create storage account
- var account = CloudStorageAccount.DevelopmentStorageAccount;
- // create blob client
- CloudBlobClient blobStorage = account.CreateCloudBlobClient();
- CloudBlobContainer container = blobStorage.GetContainerReference("guestbookpics");
- container.CreateIfNotExist(); // adding this for safety
- string uniqueBlobName = string.Format("image_{0}.jpg", Guid.NewGuid().ToString());
- CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
- blob.Properties.ContentType = "image\\jpeg";
- System.Drawing.Image imgs = System.Drawing.Image.FromFile("waLogo.jpg");
- imgs.Save(streams, ImageFormat.Jpeg);
- byte[] imageBytes = streams.GetBuffer();
- blob.UploadFromStream(streams);
- imgs.Dispose();
- streams.Close();
Now the crux of the problem was that the resulting image in storage was empty (zero bytes). And Steve Marx correctly pointed out, the key thing missing is the resetting the buffer to position zero. So the corrected code would look like this. Note the addition of line 22. If fixes things just fine.
- MemoryStream streams = new MemoryStream();
- // create storage account
- var account = CloudStorageAccount.DevelopmentStorageAccount;
- // create blob client
- CloudBlobClient blobStorage = account.CreateCloudBlobClient();
- CloudBlobContainer container = blobStorage.GetContainerReference("guestbookpics");
- container.CreateIfNotExist(); // adding this for safety
- string uniqueBlobName = string.Format("image_{0}.jpg", Guid.NewGuid().ToString());
- CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
- blob.Properties.ContentType = "image\\jpeg";
- System.Drawing.Image imgs = System.Drawing.Image.FromFile("waLogo.jpg");
- imgs.Save(streams, ImageFormat.Jpeg);
- byte[] imageBytes = streams.GetBuffer();
- streams.Seek(0, SeekOrigin.Begin);
- blob.UploadFromStream(streams);
- imgs.Dispose();
- streams.Close();
But the root issue I still have here is that the original code sample is pulling a byte array but not doing anything with it. But a byte array is still a valid method of uploading the image. So I reworked the sample a bit to support this..
- MemoryStream streams = new MemoryStream();
- // create storage account
- var account = CloudStorageAccount.DevelopmentStorageAccount;
- // create blob client
- CloudBlobClient blobStorage = account.CreateCloudBlobClient();
- CloudBlobContainer container = blobStorage.GetContainerReference("guestbookpics");
- container.CreateIfNotExist(); // adding this for safety
- string uniqueBlobName = string.Format("image_{0}.jpg", Guid.NewGuid().ToString());
- CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
- blob.Properties.ContentType = "image\\jpeg";
- System.Drawing.Image imgs = System.Drawing.Image.FromFile("waLogo.jpg");
- imgs.Save(streams, ImageFormat.Jpeg);
- byte[] imageBytes = streams.GetBuffer();
- blob.UploadByteArray(imageBytes);
- imgs.Dispose();
- streams.Close();
We pulled out the reset of the stream and replaced UploadFromStream and replaced it with UploadByteArray.
Funny part is that while both samples work, the resulting blobs are different size. And since these aren’t the only way to upload files, there might be other sizes available. But I’m short on time so maybe we’ll explore that a bit further another day . The mysteries of Azure never cease.
Next time!