Uploading a png file to Azure Blob Storage is losing transparency - c#

We are having some difficulty to figure out how upload png files to Azure Blob Storage without losing image transparency.
We are using the Azure's Storage SDK with the code below:
var storageAccount = CloudStorageAccount.Parse(*blob_connection_string*);
//create client to work with blobs
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
//already created container via azure management portal, set container reference
CloudBlobContainer container = blobClient.GetContainerReference("brand");
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
CloudBlockBlob blockBlob = container.GetBlockBlobReference(postedFile.FileName);
blockBlob.UploadFromStream(postedFile.InputStream);
}
We've tried force the ContentType property before upload like this:
blockBlob.Properties.ContentType = "image/png";
But doesn't work neither with or without this property.

Well, for those who are experiencing this issue, we've found a solution:
The problem was with using Microsoft .Net Image object. According MSDN this object work only with PNG 32 bits:
https://msdn.microsoft.com/pt-br/library/1kcb3wy4%28v=vs.110%29.aspx?f=255
We've changed the upload routine to get the posted file binary direct from the input and work like a charm!
Thanks again for the ideas who drive us to this solution!
Hugs

Related

Create container in Azure storage with c#

I have the following code:
var cloudStorageAccount = CloudStorageAccount.Parse(this._appSettings.BlobConnectionString);
this._cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer container = this._cloudBlobClient.GetContainerReference("dpd/textures/test");
await container.CreateIfNotExistsAsync();
I want to create the "test" directory inside dpd/textures/, but I keep getting this error:
The requested URI does not represent any resource on the server azure
container
What am I doing wrong?
Actually, there is no real directory in blob storage. The directory(not container) is always a part of the blob's name.
So you can just create a container like "dpd", then you can use any upload methods to upload a file like myfile.txt. During uploading file, you can specify your file name as "textures/test/myfile.txt" in your GetBlockBlobReference method. Then the directory "textures/test" is created automatically.
Simple code:
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("test1");
var myblob = cloudBlobContainer.GetBlockBlobReference("textures/test/myfile.txt");
myblob.UploadFromFile("your file path");
Test result:
And also note that, if the blob(myfile.txt) is deleted, then the directory "textures/test" will also be removed, since it's a part name of the blob.

Copy Azure CloudPageBlob to CloudBlockBlob

Have a load of Azure page blobs in an Azure storage account which need copying to block blobs so they can be set from "cold" to "Archive" storage tier. The page blobs are created by SQL server (pre 2016) BACKUP TO URL.
I spoke to Microsoft about this and they suggested AzCopy with Azure File blob as a stepping stone, e.g. Page blob -> block blob (file storage) -> block blob (Blob storage). This all works fine in AzCopy or GUI based Azure tools but I need to automate it and build in some resilience.
Problem I have is I cannot get a CloudPageBlob to copy to CloudBlockBlob
not matter how I cast it. This is a cut-down example to show (lack of) progress and how I'm going about this. I will wrap this in a Task<> in production but I cannot get the .StartCopy to work. Any ideas?
CredentialEntity ce = Utils.GetBlobCredentials();
StorageCredentials sc = new StorageCredentials(ce.Name, ce.Key);
CloudStorageAccount storageAccount =
new CloudStorageAccount(new StorageCredentials(ce.Name, ce.Key), true);
CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer sourceContainer = cloudBlobClient.GetContainerReference(#"archive");
CloudBlobContainer targetContainer = cloudBlobClient.GetContainerReference(#"xfer");
CloudPageBlob source = sourceContainer.GetPageBlobReference("test.bak");
CloudBlockBlob target = targetContainer.GetBlockBlobReference("new.bak");
//target.StartCopy(source);
//target.StartCopyAsync()

How to get image dimensions when is stored in azure blob storage?

I have image in blob and I want to read image dimensions (width and height)
This is my function to read from blob:
private static CloudBlockBlob ReadBlockBlob(string input, IConfigurationRoot config)
{
CloudStorageAccount storageAccount = new CloudStorageAccount(
new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(config["storageAccountName"], config["storageKeyValue"]), true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(config["blobContainer"]);
return container.GetBlockBlobReference(input);
}
I don't see any useful metadata in CloudBlobContainer nor in CloudBlockBlob.
Any idea how to get dimensions of image from blob?
Thank you
You can not directly get the dimensions of an image blob that exists on Azure Storage via the properties and metadata of the blob. The only way is to download the image blob and convert it to System.Drawing.Image via methods System.Drawing.Image.FromFile or System.Drawing.Image.FromStream to get Image.Width & Image.Height.
Or else, you need to first add metadata to the blob to store the image dimensions when uploading an image. Then, you can get the dimensions of an image from the blob metadata without downloading. I recommend this way to avoid downloading for those large images.

How to upload List of images on azure and retrieve addresses of uploaded images

I am doing Mvc asp.net project. i want to upload four images on azure blob storage, i am uploading one image at a time using following method
public static string UploadToBlob(string fileName, byte[] data)
{
MemoryStream file = new MemoryStream(data);
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("ConnectionSetting"));
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
// Create the container if it doesn't already exist.
container.CreateIfNotExists();
CloudBlockBlob blob = container.GetBlockBlobReference(fileName);
blob.Properties.ContentType = "image/jpg";
blob.UploadFromStream(file);
string url = blob.Uri.ToString();
return url;
}
it's takes four call to azure server, so i want do it in one call i.e upload List of four images on azure and retrieve addresses of uploaded images.
You need to make separate service calls to upload separate blobs. However, you should be sharing most of the common code in that method. Namely, everything above actually getting the blob reference. This will save you several service calls by only calling CreateIfNotExists on the container once.

Upload image to Azure blob storage from Windows Phone. Not creating

I am using Windows Azure to store images in my windows phone application.
The camera takes a photo and the chosen photo stream is then uploaded. However it is throwing NO error but is not uploading?
var blobContainer = CloudStorageContext.Current.Resolver.CreateCloudBlobClient();
var container = blobContainer.GetContainerReference("pics");
var blob = container.GetBlobReference("picture.jpg");
blob.UploadFromStream(e.ChosenPhoto, response => { MessageBox.Show(blob.Uri.ToString()) });
I don't have a clue what is happening. The Resolver contains the correct user, key and urls. The container "pics" does exist, but no image is being uploaded. The message box pops up with a url which does not exist.
UPDATE - There seems to be a simular (well almost identical) question posted here - Uploading a photo stream from camera into azure blob in WP7. However the upper case container name is not an issue here, so that solution did not fix this
I have an application (Windows Phone 8) that uploads an image taken to an Azure webrole, which in turn stores the image in an Azure Storage Blob. The code below is how the server stores the images. Again, this code does not run on the phone, but you can use it as a reference.
string randomGUID = locationID
+ "-"
+ Guid.NewGuid().ToString();
//Retrieve storage account from application settings
CloudStorageAccount storageAccount = GetStorageAccount();
//Create blob client
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
//Retrieve reference to images container
CloudBlobContainer container = blobClient.GetContainerReference(
RoleEnvironment.GetConfigurationSettingValue("BlobContainer"));
//Retrieve references to the blob inside the container
CloudBlockBlob blockBlob = container.GetBlockBlobReference(randomGUID);
blockBlob.UploadFromStream(imageToUpload);
The variable imageToUpload is of the type Stream.
As you can see, this is pretty straightforward code. Perhaps your problem has to do with the lambda expression you have in UploadFromStream?

Categories