Using ImageKit to Deliver Responsive Images with Azure Storage & .NET Core
I’ve recently been working on a small business (that’s not safe for work) called Gay Media Data. The applications runs .NET 5 and is hosted on a Microsoft Azure Linux App Service Plan. The photos and other assets are stored in Azure Storage Containers.
When I initially developed the application, I knew I was going to be handling a ton of photos from a variety of studios/affiliates that I work with. Additionally, I knew I had to create thumbnails of images. So, I started off by creating an Azure Function and using an open-source library called ImageSharp to take images, save them at a slightly reduced quality, and to generate a thumbnail of a specific size.
However, as time went on, I discovered that for some images, the primary image, I needed to generate a third size of an image that was smaller than the thumbnail. No problem, I thought, I can handle two different sizes of images.
However, one thing always bugged me: these images (or photos, sorry, I’m going to use those terms interchangeably) would look blurry on mobile devices and retina displays. This is because I would save a thumbnail as, for example, 150px wide and when you’d look at the photo on a mobile phone (or devices with a high pixel density) it would “resize” the image to fit the display.
I ignored this for the longest period of time because I didn’t want to manage 3–6 different sizes of images.
So, I began looking into solutions and came across ImageKit! The offer integration with Amazon S3, Google Cloud Storage, Azure Storage, and a normal Web folder.
Because my photos and containers are publicly available, I went with the Web integration because it was the most straightforward. I didn’t have to worry about SAS Tokens, etc.
The next step was replacing the Azure Storage URLs that I had stored in the database to point to the new ImageKit CDN URL. For this, I decided to write a very lightweight service called “CdnService.”
Basically _appSettings is a Class that gets populated from the Configuration file. So, it contains all the settings.
Now, you would register this service in your Startup.cs class and then inject it in your _ViewImports.cshtml.
Then, you could do something like this:
And with that, when the page loads up the image it grabs the image from the database, replaces the original Azure Storage Url with the CDN Url, and then applies a transformation (in this case, requesting different widths of an image).
You’ll notice I’m using srcset. There are a variety of different ways you can implement responsive images, and I’d admit that I’m still learning a lot as I’m becoming more of a front-end developer, but this implementation is working really well for me.
And now, when I view a photo on any device, the photo is crystal clear and loaded extremely fast.
Before I forget, one important thing to do when implementing ImageKit is to send client hints so they know more about the device that’s requesting the image. This is done through response headers. In my Startup.cs, I have the following:
By doing this, ImageKit is also able to deliver the best image format. So, in many cases, it’s delivering the new WebP image. If the user’s browser or device isn’t capable of receiving WebP images, they automatically deliver the original JPG format.
So, in summary, to say I’m in love with this solution is an overstatement. I no longer have to worry about maintaining a variety of image sizes or formats. Additionally, if I decide to change my site’s layout at any given time, I wouldn’t have to mass regenerate thumbnails!
Have you found a similar solution? How do you handle multiple image sizes and formats? Let me know in the comments!