As of late I've begun exploring different avenues regarding Google's Flutter framework.
For the people who don't have the foggiest idea, Flutter is a cross-stage platform framework (Same as React Native) based on Dart programing language.
After playing with the framework and understanding the best practices (thank you Effective Dart), I started to build our (Cloudinary’s) Flutter SDK.
In the following article, I’ll explain why we decided to implement this SDK, how you can use it, and what good it will do for your application.
The problem
One of the biggest pain points for a mobile developer is dealing with performance issues caused by handling many assets (images, videos, etc.) on multiple devices with different size screens.
In one of my previous jobs, I was responsible for an application that allowed users to download images into their phones and set them as backgrounds for the home screen, lock screen, or both.
This application required pulling big JSON files with all the image information, including multiple fields such as title, URL, created date, etc…
On the main screen, I had to present a thumbnail (a small image representation of a larger image) of each image.
Tapping a thumbnail would direct the user to a screen where the image was shown full screen.
These 2 screens already required multiple versions of the same image. You can’t present a full-screen image as a thumbnail image because you’ll get a pixelated result which yields a bad user experience. On the other hand, we didn't want to present the full-screen image because that would cause a long load time for the screen, which is again a bad user experience.
Moreover, every image came in a different size, so we had to find a way to present them uniformly.
To add to the complexity, we wanted this app to work with different screen sizes (iPhones, iPads, different Android devices, and Android base tablets) which require different image sizes.
The scenario in which we have a single image that needs to be displayed in many different sizes is very common. How can we best handle it? Let’s go through some possibilities.
One solution would be to get it in one size for the client and manipulate it for our needs. Unfortunately, this solution wouldn't be efficient and could cause a long processing time.
We could handle it on the server side (if we have one). We could create multiple URLs and send them to the client. But that would create big JSONS would be harder to handle and parse.
That’s where Cloudinary comes in.
The solution
What’s Cloudinary?
Cloudinary is a platform that allows you to quickly and easily create, manage and deliver digital experiences across any browser, device, and bandwidth.
Working with Cloudinary
Setup
The first thing you need to do is go to the Cloudinary website and sign-up for a free account.
You can find the Git repository for the Cloudinary Flutter SDK here.
To integrate Cloudinary into your app you can use:
cloudinary_flutter: ^0.0.1
cloudinary_dart: ^0.0.7
Configuration
Once the package is integrated, we’ll need to set up our Cloudinary object.
Your cloud name will appear in the dashboard where you created your account.
CloudinaryContext.cloudinary = Cloudinary.fromCloudName(cloudName: '<Cloud_name>');
Now that you have your Cloudinary object set and ready to use, the MAGIC starts.
Transformations
At the start of this article, I presented the problem where we have one asset, but we need it in many different sizes and aspect ratios. Let’s see how we can achieve that very easily by applying Cloudinary’s transformations.
Here’s the original image called ‘dog’:
Crop
You can easily create a thumbnail(500x500) for your main screen:
String url = (CloudinaryContext.cloudinary.image('dog')
..transformation(Transformation()
..resize(Resize.crop()
..width(500)
..height(500))))
.toString();
This code creates a new string URL using the Cloudinary object that was initiated in the previous step. The image function builds the URL using the publicId of the specified image.
When calling transformation you can specify the action you want to perform. In this case, the resizeaction is applied with the Crop and the values for width and height , Finally, the toString()turns the object into a string.
This code will output a URL for the following image:
As we can see we got the 500x500 thumbnail we wanted, but the result could be improved. We lost the dog and we can only see white fur (not optimal at all).
What can we do? OH! Cloudinary has a few more tricks up its sleeve! Another COOL feature we can use is “gravity” where we can ask Cloudinary to focus on the most interesting object in the image.
Gravity
String url = (CloudinaryContext.cloudinary.image('dog')
..transformation(Transformation()
..resize(Resize.crop()
..width(500)
..height(500)
..gravity(Gravity.autoGravity()))))
.toString();
And as we can see the result is much better. The focus is on the dog’s face.
Quality
Let’s try another scenario. You want to deliver a 2k resolution image, which is quite a large file, and you don’t need to present it in its best form. Roaming can’t always handle big bandwidth. To make the image lighter we can use the Cloudinary “quality” feature.
Here’s the original image (5MB)
With Cloudinary we can do the following:
String url = (CloudinaryContext.cloudinary.image('dog')
..transformation(Transformation()
..delivery(Delivery.quality(Quality.auto))))
.toString();
This code will produce the following URL:
After this transformation, the size is reduced to 626.56 KB and it’ll be faster to load this image on a mobile device.
Cloudinary’s Image Widget
So far we’ve seen how to generate URLs and we can manually put them into an image widget, but Cloudinary gives us an extra zing, an image widget that can integrate with everything we’ve implemented so far.
CldImageWidget(
publicId: 'dog',
transformation: Transformation()
..resize(Resize.crop()
..width(500)
..height(500)
..gravity(Gravity.autoGravity()))
..delivery(Delivery.quality(Quality.auto)),
),
In the code snippet above we see that we create the image widget and we give the following attributes:
Public Id
Resize crop, with width=500 and height=500 and Gravity auto
Delivery with quality auto
This code will generate the URLs we’ve seen before and will inject them into the image widget.
To sum up!
In this blog, you saw how Cloudinary can handle the same asset in many sizes and qualities. That’s just the tip of the iceberg. Cloudinary has many other features that you can use when managing the media in your apps.
I encourage you to visit Cloudinary’s documentation to get the most out of the platform.
The Cloudinary SDK can also be found on Android and iOS and 14 more languages you can find at Cloudinary’s git.
Top comments (0)