Sujit.Warrier
Sujit.Warrier

Reputation: 2869

Image management in azure cloud environment

So I have a asp.net web forms application which has a lot of images to be displayed in each page. while uploading these images are stored to the database. Before moving to cloud I used to check the file system if the image is present, if it was I fetched that and displayed it else I used to create the image in the file system and then use it. Now i want to move this application to cloud and have implement similar logic only difference is instead of file system I am saving to azure blob storage account and fetching the images from there. The code given below is used to upload and fetch images from blob storage

          CloudBlobContainer BlobContainer = Img.GetCloudBlobContainer();
                CloudBlockBlob blob = BlobContainer.GetBlockBlobReference(picture_id + "_HighRes.Jpeg");
                var blobs = BlobContainer.ListBlobs(picture_id + "_HighRes.Jpeg");
                if (blobs.Count()>0)
                {

                    foreach (var i in blobs)
                    {
                        Picture_name = i.Uri.ToString();
                    }
                }
                else
                {
                    SqlConnection Db_Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DB_connection"].ToString());
                    DataSet ds_pic = new DataSet();
                    Db_Con.Open();
                    SqlDataAdapter sd_pic = new SqlDataAdapter("select PictureBinary FROM Picture where Id=" + pic_id, Db_Con);
                    sd_pic.Fill(ds_pic);
                    Db_Con.Close();
                    byte[] picbin = (byte[])ds_pic.Tables[0].Rows[0][0];
                    ImageConverter ic = new ImageConverter();
                    System.Drawing.Image img = (System.Drawing.Image)ic.ConvertFrom(picbin);
                    //img.Save(HttpContext.Current.Server.MapPath(imagePath + picture_id + ".Jpeg"), System.Drawing.Imaging.ImageFormat.Jpeg);
                    System.Drawing.Image img4 = null;
                  // VariousQuality(img, picture_id, 200, "_HighRes.Jpeg");
                   // Picture_name = imagePath + picture_id + "_HighRes.Jpeg";
                   BlobContainer = Img.GetCloudBlobContainer();
                    blob = BlobContainer.GetBlockBlobReference(picture_id + "_HighRes.Jpeg");
                    blob.UploadFromStream(new MemoryStream(picbin));
                  blobs = BlobContainer.ListBlobs(picture_id + "_HighRes.Jpeg");
                    foreach (var i in blobs)
                    {
                        Picture_name = i.Uri.ToString();
                    }
                  return Picture_name;

Now this works but as you can imagine the site is pretty slow. Is there a better way to handle images in cloud

Upvotes: 0

Views: 118

Answers (2)

JuanK
JuanK

Reputation: 2094

There are many possible ways.

I'd list some of my suggestions

  1. optimize your jpeg images for the web, services like https://tinyjpg.com/ have a significant improvement in image sizes
  2. Ensure your Storage account is in same or most near region to your client connections
  3. Use cache as much as possible, one hyper boost could be to use Redis cache for the most recent uploaded images or maybe for the top requested images. you need to try what is best for your application
  4. Another cache strategy could be Use azure CDN Integrate a Storage Account with CDN
  5. Use parameterized queries when accessing databases to prevent SQL injection (thanks @Daniel Mann)

Extra info

As I see in your code you're getting the images directly to your backend, this means that any browser/client trying to get the images is causing an overhead because essentially you're downloading the image twice

  1. Downloading images from storage to web App server side
  2. Downloading from server side to browser

An image in a website is usually a public image, so you can download the image directly to browser without pass it thru the backend. You'll need only to set the blob/container access to public.

If your image isn't public and requires authentication you will need to create SAS link to each image file giving access to the current client thru a link created specifically for this session and that link could expire after a while-

Shared Access Signatures, Part 1: Understanding the SAS Model

Shared Access Signatures, Part 2: Create and Use a SAS with the Blob Service

Upvotes: 1

Brij Raj Singh - MSFT
Brij Raj Singh - MSFT

Reputation: 5113

For images the best option is to go with Azure CDN, although it'll use the same storage and blob containers, but it scales well because the images are now coming from a static url of blob, and there will be a parallel connection for images now so I am quite sure fetch would look really fast as its happening in parallel with other content, essentially all the static content like images, JavaScript, css if can be should be kept in different domains, the browser can make multiple parallel connections per domain, and thus the page load is faster.

Using Azure CDN for Images - https://azure.microsoft.com/en-us/documentation/articles/cdn-serve-content-from-cdn-in-your-web-application/#serve-static-content-from-an-azure-cdn-endpoint

Tuning Web Page tips - http://www.brijrajsingh.com/2012/07/few-general-rules-with-scripts-css.html

Upvotes: 1

Related Questions