Moving from self-hosted image service to Cloudinary
Image manipulation is hard. Handling images in the long term is even harder. Here at Dose we have a lot of images and a number of ways to serve them. We have Android and iOS apps, as well as completely responsive websites, so each image has the potential of getting manipulated multiple times depending on the device, orientation, and how we optimize an image for a certain platform.
Handling this ourselves
We used to have an internal image service that took an author’s uploaded image and handled some pre-processing. On upload, we’d make sure it’s within a max width and encoded correctly. Animated GIF? We’d have to convert the file to MP4 and WEBM also. This would end up adding extra load on our servers and more space taken in our S3 account.
When an asset was requested with a certain height/width combination we’d check to see if we had it in our S3 bucket. If not we’d return the master asset and kick off a queue job to create it then add it to the bucket for the next request. As you can imagine, the usage was huge. Want to change the article promo image from 500px width to 475px width? That would invalidate all previous images and we’d need to recreate all new images the next time they were requested. What a mess!
If your product is not image manipulation, then don’t do this yourself. Services like Cloudinary do this much more efficiently and much better than you will, so use them. And if you’re worried about the cost, think about how much it’ll cost you in development and upkeep, as well as hosting, storage, and delivery costs. More on that later.
Getting Started with Cloudinary
Cloudinary is the market leader in providing a comprehensive cloud-based image management solution. Cloudinary is being used by tens of thousands of web and mobile application developers all around the world, from small startups to large enterprises. We are here to cover your every image-related need.
Cloudinary has taken the massive task of handling and manipulating images and broke it down to something very simple — URL manipulation.
Take the following image url:
http://res.cloudinary.com/demo/image/upload/sample.jpg
Let’s say we’d like to resize this to a max width of 300px, you’d get
http://res.cloudinary.com/demo/image/upload/w_300/sample.jpg
How about we restrict the height to 150px
http://res.cloudinary.com/demo/image/upload/w_300,h_150/sample.jpg
Well, we got the size that we wanted, but it looks pretty bad right now. We’ll need to make some adjustments. Let’s crop it to fit the space that we need
http://res.cloudinary.com/demo/image/upload/w_300,h_150,c_fit/sample.jpg
Yeah, this looks a lot better!
Combining Transformations
Combining transformations is just as straightforward as single transformations, all you have to do is add another segment to the URL
http://res.cloudinary.com/demo/image/upload/w_300,h_150/c_crop,w_50,h_50,x_100,y_75/sample.jpg
So with this example we are:
- Resizing the image to 300px X 150px then
- Cropping the image to be 50px X 50px and moving the X, Y point to 100, 75 in order to focus in on the yellow part of one of the flowers.
File Type Transformations
This is by far one of the most powerful features of Cloudinary. Say we are uploading a GIF, but want to optimize it and change it to a MP4.
http://res.cloudinary.com/demo/image/upload/kitten_fighting.gif
would turn into
http://res.cloudinary.com/demo/image/upload/kitten_fighting.mp4
Just by changing the extension of the file in the URL will make this conversion for you. No more keeping track of different file references or different hashes. Only ask for a different file extension!
Programmatic SDKs
It’s all well and good that we can convert any file asset via a URL, but if you want to make these changes more programmatically, you can use one of their many SDKs. For this example, we’ll be using their PHP SDK
In my initial example, we ended with the final URL of
http://res.cloudinary.com/demo/image/upload/w_300,h_150,c_fit/sample.jpg
for our image. In the PHP SDK, we’d be able to do
$transformations = ['width' => 100, 'height' => 150, 'crop' => 'fill'];
$url = cloudinary_url('sample.jpg', $transformations);
and multiple transformations, like our second example, would look like
$transformations = ['transformation' => [
['width' => 300, 'height' => 150],
['width' => 50, 'height' => 50, 'crop' => 'crop', 'x' => 100, 'y' => 75]
]];
$url = cloudinary_url('sample.jpg', $transformations);
Migrating to Cloudinary
Cloudinary has taken the hard work out of migrating assets over to their platform. There are currently a few options to choose from.
- Add a full URL to your current image and Cloudinary will automatically pull this in for you.
- Set up an auto upload mapping to your S3 bucket. When this “virtual” directory is requested, it will pull the asset from your bucket into your Cloudinary account.
Why We Chose Cloudinary
Before moving forward with anything new, we went through a diligent research period where we were looking at a handful of SaaS options as well as possibly redesigning our current in-house system. As we worked through the options one thought became very clear — handling our own system didn’t make sense. There are a good handful of services that are more cost effective and feature rich than something that we could ever make. Our business is not handling images. Just the cost of AWS instances, storage, and CDN fees were tens of thousands of dollars per month. Now take developer costs to maintain and add to the system, and it adds up quickly. But even more importantly, each time something would break or need to be added to our image service, it would take attention away from more important tasks or services.
After evaluating a number of image and CDN services, we moved forward with Cloudinary for a number of reasons:
- They were very attentive. They set up multiple meetings with their sales and tech teams to answer all of our questions and to help get us the best price for the resources we need. Even now, after the “sale”, they continue to reach out personally to share new features that haven’t been published yet and check in on analytics and our performance.
- Price. Their price is a LOT cheaper than running all of our instances, storage, and CDN through AWS.
- Features. The flexibility and amount of features they have for image handling is impressive and there would be no realistic way that we’d have the bandwidth in order to make similar features ourselves. Their system makes it very easy to make adjustments on the fly to see what combinations perform, and look better.
- Uptime. Since the majority of our content is showing images, if the images aren’t available we aren’t able to provide the value to our users that we need to. Since moving to Cloudinary, our image uptime has been spectacular and image responsiveness has been significantly faster too.
Summary
We have simplified our image handling process over the last 6 months since starting to work with Cloudinary. They can easily handle our 4.5 Million images (and counting) and over 1.4 Billion requests per month. They also provide insight to help us further improve our performance on our sites. Site performance and user experience are not taken lightly, so we are very happy with our decision to utilize their services. Some other helpful points are
- Great documentation
- A bunch of add-on plugins like JPEGmini and Imagga
- Tons of transformation options like watermarks, custom pixelation, and even PDF to image conversion
- Automatic responsive image handling
- Video management and transformations
- Automatic backups to S3
- Newly introduced “Auto Everything”
As an aside, we’re just sharing this article and information as happy customers. Cloudinary did not commission this article nor give us any incentive for writing it. We just want to share our experience.
This article was originally posted on chrisgmyr.dev.