iOS image manipulation

After you or your users have uploaded image assets to Cloudinary, you can deliver them via dynamic URLs. You can include instructions in your dynamic URLs that tell Cloudinary to manipulate your assets using a set of transformation parameters. All manipulations are performed automatically in the cloud and your transformed assets are automatically optimized before they are routed through a fast CDN to the end user for optimal user experience.

For example, you can resize and crop, add overlay images, blur or pixelate faces, apply a large variety of special effects and filters, and apply settings to optimize your images and to deliver them responsively.

Cloudinary's iOS library simplifies the generation of transformation URLs for easy embedding of assets in your iOS application.

See also: iOS video manipulation

Generate image URLs

Use the createUrl method to generate an image URL.

cloudinary.createUrl().generate("sample.jpg")

// returns: https://res.cloudinary.com/demo/image/upload/sample.jpg

Add Transformations

You can add transformations to your createUrl method by defining a transformation object and then passing it with the setTransformation method.

let tr = CLDTransformation().setWidth(100).setHeight(150).setCrop(.crop)
let url = cloudinary.createUrl().setTransformation(tr).generate("sample.jpg")

// returns: https://res.cloudinary.com/demo/image/upload/c_fill,h_150,w_100/sample.jpg

Chaining Transformations

You can link transformations together with the chain method, where each transformation is applied to the result of the previous transformation:

let tr = CLDTransformation().setWidth(100).setCrop(.fit).chain().setAngle(15)
let url = cloudinary.createUrl().setTransformation(tr).generate("sample.jpg")

// returns: https://res.cloudinary.com/demo/image/upload/c_fit,w_10/a_15/sample.jpg

For example, the following code crops the image to 150x150, rounds the corners, applies a sepia effect, adds text to the top center of the resized image, and then rotates the entire result by 20 degrees.

let url = cloudinary.createUrl().setTransformation(CLDTransformation()
   .setHeight(150).setWidth(150).setCrop(.crop).setEffect(.sepia).setRadius(20).chain()
   .setOverlayWithLayer(CLDTextLayer()
      .setFontFamily("Arial").setFontSize(60).setText("This is my picture"))
   .setGravity(.north).setY(20).chain()
   .setAngle(20))
   .generate("mypic.jpg")

For more information and examples of image transformations, see Applying common image transformations.

Download images

Use the fetchImage method of the CLDDownloader class to download an image. The method accepts a url parameter with the location of the image to download. Every download request returns an instance of CLDFetchImageRequest, which allows options such as cancelling, suspending or resuming the download. The download is performed asynchronously in a separate thread so you must also provide a callback closure to handle the results of the download:

let downloader:CLDDownloader = cloudinary.createDownloader()
let myImage = downloader.fetchImage(url, progress: { (bytes, totalBytes, totalBytesExpected) in
    // Handle progress
  }) { (responseImage, error) in
    // responseImage is an instance of UIImage
    // error is an instance of NSError
  }

Image Caching

The first time that the fetchImage method is called for downloading a particular resource, Cloudinary also stores it in the device's cache. Each subsequent call to fetchImage first attempts to find the image in the local cache, and retrieves it from the cache if it was found. This default behavior can be customized with the cachePolicy, cacheMaxDiskCapacity and cacheMaxMemoryTotalCost properties of your CLDCloudinary instance:

Property Type Description
cachePolicy CLDImageCachePolicy Set the caching policy for downloaded images
Possible values:
-CLDImageCachePolicy.none
-CLDImageCachePolicy.memory
-CLDImageCachePolicy.disk (default)
cacheMaxDiskCapacity Int (Relevant only if the disk option is selected for policy) The maximum capacity of the disk cache in bytes. Default: 150 * 1024 * 1024
cacheMaxMemoryTotalCost Int (Relevant only if the memory option is selected for policy) Maximum size for the memory cache in bytes. Default: 150 * 1024 * 1024

For example, to use the device's memory for caching images, and limiting the disk cache size to 50 MB:

cloudinary.cachePolicy = CLDImageCachePolicy.disk
cloudinary.cacheMaxDiskCapacity = 50 * 1024 * 1024

Deliver images using UI extensions

The Cloudinary SDK provides extensions to three iOS UI elements for presenting images. These extensions provide a cldSetImage method that automatically fetches and downloads an image in the background, as well as setting it to be displayed in the UI. The extension is available for:

  • UIView
  • UIImageView
  • UIButton

For example, setting a UIImageView component named "photoImageView" to fetch and display an image that was uploaded with the public id of "dog", scaled to 400 pixels wide:

let transformation = CLDTransformation().setCrop(.scale).setWidth(400)
photoImageView.cldSetImage(publicId: "dog", cloudinary: cld, transformation: transformation)

Apply common image transformations

This section provides an overview and examples of the following commonly used image transformation features, along with links to more detailed documentation on these features:

Keep in mind that this section is only intended to introduce you to the basics of using image transformations with iOS.

For comprehensive explanations of how to implement a wide variety of transformations, see Image transformations. For a full list of all supported image transformations and their usage, see the Image transformation reference.

Resizing and cropping

There are a variety of different ways to resize and/or crop your images, and to control the area of the image that is preserved during a crop.

The following example uses the fill cropping method to generate the dynamic URL for an image that completely fills the requested 250x250 size while retaining the original aspect ratio. It uses face detection gravity to ensure that all the faces in the image are retained and centered when the image is cropped:

let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setWidth(250).setHeight(250).setGravity("faces").setCrop("fill"))
  .generate("family_bench.jpg")
Original image before face recognition cropping Original image Fill cropping with 'faces' gravity Fill cropping with 'faces' gravity

For details on all resizing and cropping options, see resizing and cropping images

Converting to another image format

You can deliver any image uploaded to Cloudinary in essentially any image format. There are two main ways to convert and deliver in another format:

  • Specify the image's public ID with the desired extension.
  • Explicitly set the desired format using the fetchFormat parameter.

For example:

Generate the dynamic URL for an image in the GIF format by specifying the file extension:

let url = cloudinary.createUrl().generate("sample.gif")

Generate the dynamic URL for an image in the GIF format by specifying the setFormat parameter:

let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setWidth(350).setCrop("scale").setFormat("gif"))
  .generate("cloud_castle.jpg")

For more details, see Image format support.

Applying image effects and filters

You can select from a large selection of image effects, enhancements, and filters to apply to your images. The available effects include a variety of color balance and level effects, tinting, blurring, pixelating, sharpening, automatic improvement effects, artistic filters, image and text overlays, distortion and shape changing effects, outlines, backgrounds, shadows, and more.

For example, the code below generates the dynamic URL for an image with a cartoonify effect, a rounding corners effect, and a background color effect (and then scales the image down to a height of 300 pixels).

let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setEffect("cartoonify").chain()
    .setRadius("max").chain()
    .setEffect("outline:100").setColor("lightblue").chain()
    .setBackground("lightblue").chain()
    .setHeight(300).setCrop("scale"))
  .generate("actor.jpg")

An image with several transformation effects

For more details on the available image effects and filters, see Applying image effects and filters

Adding text and image overlays

You can add images and text as overlays on your main image. You can apply the same types of transformations on your overlay images as you can with any image and you can use gravity settings or x and y coordinates to control the location of the overlays. You can also apply a variety of transformations on text, such color, font, size, rotation, and more.

For example, the transformation below overlays a couple's photo on a mug image. The overlay photo is cropped using face detection with adjusted color saturation and a vignette effect applied. The word love is added in a pink, fancy font and rotated to fit the design. A balloon graphic is also added. Additionally, the final image is cropped and the corners are rounded.

let url = cloudinary.createUrl()
    .setTransformation(CLDTransformation()
    .setWidth(400).setHeight(250).setGravity("south").setCrop("fill").chain()
    .setOverlay("nice_couple").setWidth(1.3).setHeight(1.3).setGravity("faces").setFlags("region_relative").setCrop("crop").chain()
    .setEffect("saturation:50").chain()
    .setEffect("vignette").chain()
    .setFlags("layer_apply").setWidth(100).setRadius("max").setGravity("center").setY(20).setX(-20).setCrop("scale").chain()
    .setOverlay("balloon").setHeight(55).chain()
    .setEffect("hue:-20").setAngle(5).chain()
    .flags("layer_apply").setX(30).setY(5).chain()
    .setOverlay("text:Cookie_40_bold:Love").setEffect("colorize").setColor("#f08").chain()
    .setAngle(20).setFlags("layer_apply").setX(-45).setY(44).chain()
    .setWidth(300).setHeight(250).setX(30).setCrop("crop").chain()
    .setRadius(60))
  .generate("coffee_cup.jpg")

An image with many transformations and overlays applied

Image optimizations

By default, Cloudinary automatically performs certain optimizations on all transformed images. There are also a number of additional features that enable you to further optimize the images you use in your iOS application. These include optimizations to image quality, format, and size, among others.

For example, you can use the auto value for the quality attribute to automatically deliver an image that minimizes file size while meeting the required quality level. In the example below, the automatic quality parameter is applied, resulting in a 50% file size reduction (1.4MB vs. 784KB) with no visible change in quality.

let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setQuality("auto"))
  .generate("pond_reflect.jpg")

50% file size optimization using the auto quality feature

For an in-depth review of the many ways you can optimize your images, see Image optimization

Responsive images

Responsive design is a method of providing an optimal viewing experience to users, tailored to their device, window size, orientation, and resolution. An App designed responsively adapts its layout to the viewing environment, resizing and moving elements dynamically and based on the properties of the device the App is being displayed on.

When it comes to images, a responsively designed App should not just send the highest resolution image and then use client-side resizing to display the image on all the various devices: that would be a huge waste of bandwidth for users on small, low-resolution displays. The best solution is to prepare an image in various resolutions and sizes, and then deliver the best possible resolution image, based on the device's resolution and the dimensions available, without needlessly wasting bandwidth or loading time. Cloudinary can help reduce the complexity with dynamic image transformations. You can simply build image URLs with any image width or height based on the specific device resolution and window size. This means you don't have to pre-create the images, with dynamic resizing taking place on-the-fly as needed.

A responsive method is available for the Cloudinary UIImageView component. Use the cldSetImage method to automatically fetch and download the optimal image in the background, as well as setting it to be displayed in the UI. To make the generated URL responsive, pass the cldSetImage method 5 parameters: the publicId of the image, the Cloudinary resourceType, the Cloudinary instance, the responsive parameters, and any transformation to apply to the image. The responsive parameters are passed as a CLDResponsiveParams object as follows:

  • autoWidth: boolean - adjust according to the available width
  • autoHeight: boolean - adjust according to the available height
  • cropMode: String - the crop mode to apply when adjusting the image
  • gravity: String - the location in the image to be used as the focus for the transformation

Instead of specifying the 5 responsive parameters individually, you can add one of the following "preset" methods:

  • autoFill(): Adjusts both height and width of the image, retaining the aspect-ratio, to fill the ImageView, using automatic gravity to determine which part of the image is visible if necessary (shortcut for: true, true, "fill", "auto").
  • fit(): Adjusts both height and width of the image, retaining the aspect-ratio, to completely fit within the bounds of the ImageView. The whole image will be shown (shortcut for: true, true, "fit", "center")

For example, setting a UIImageView component named "photoImageView" to responsively fetch and display an image that was uploaded with the public id of "sample", in JPEG format, and automatically resized to fill the available width and height:

let transformation = CLDTransformation().setFetchFormat("jpg")
let params = CLDResponsiveParams(autoWidth: true, autoHeight: true, cropMode: "fill", gravity: "auto")         
photoImageView.cldSetImage(publicId: "sample", 
    cloudinary: cld, resourceType: "image", 
    responsiveParams: params, transformation: transformation)

Which is equivalent to:

let transformation = CLDTransformation().setFetchFormat("jpg")
let params = CLDResponsiveParams.autoFill()         
photoImageView.cldSetImage(publicId: "sample", 
    cloudinary: cld, resourceType: "image", 
    responsiveParams: params, transformation: transformation)

The cldSetImage with method retrieves the exact available dimensions for the UIImageView component and then rounds up the height and width for the image to the nearest step (100 by default). For example, if the exact width is 284 logical pixels then the requested width is rounded up to 300 pixels. This prevents too many image versions being generated and reduced cache hits for subsequent requests from other devices.

The default values for the responsive calculation can be overridden by calling the setStepSize, setMinDimension and/or setMaxDimension methods of CLDResponsiveParams and passing the new values (default values are 50, 50 and 350 logical pixels respectively).

For example, to set the step size to every 100 logical pixels and limit the dimensions to between 100 and 300 logical pixels:

let transformation = CLDTransformation().setFetchFormat("jpg")
let params = CLDResponsiveParams.autoFill() 
    .setMaxDimension(300)
    .setMinDimension(100)
    .setStepSize(100)        
photoImageView.cldSetImage(publicId: "sample", 
    cloudinary: cld, resourceType: "image", 
    responsiveParams: params, transformation: transformation)