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!
Pingback: Windows Azure and Cloud Computing Posts for 7/29/2011+ - Windows Azure Blog
I searched around for a while and this is by far the simplest and most concise example of uploading to blob storage that I found. You definitely saved me a bunch of time getting a simple storage case up and running.
Thanks Brent!
I’m glad it was helpful Bryan. 🙂
Some time has passed since this post, but I wanted to take a moment to thank you for it. I found this post to be extremely helpful/useful.
Excellent post, helps people to find quick examples of every day operations:)
About the different sizes:
I don’t think that it has anything to do with Azure. I think if you look at the sizes of the byte arrays you are trying to save in both cases, they will be different. I predict that stream.GetBuffer() will return a bigger array then stream.ToArray() because GetBuffer() returns unused trailing bytes of the buffer.
thank you very much the solution works perfectly
Pingback: Read a PDF file and return as stream from a WCF service? | PHP Developer Resource
Thanks, It helped me a lot…
– Sachin Magdum
Thanks it helped lot of time 🙂
Thanks,it’s very useful to me.