> ## Documentation Index
> Fetch the complete documentation index at: https://cloudinary.com/documentation/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS image transformations


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 transform your assets using a set of transformation parameters. All transformations 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 transformation](ios_video_manipulation)

## Generate image URLs

Use the `createUrl` method to generate an image URL.

```swift
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. 

```swift
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
```

> **TIP**:
>
> In general, when using an SDK, you will probably take advantage of the SDK parameter names for improved readability and maintenance of your code. However, you can also optionally pass a **raw_transformation** parameter, whose value is a literal [URL transformation](transformation_reference) definition. Note that the string you pass as the raw transformation value will be appended as is (with no processing or validation) to the **end** of any other transformation parameters passed in the same component of the transformation chain. 
> For example:
> ```swift
let tr = CLDTransformation().setRawTransformation("w_100,h_150,c_crop")
let url = cloudinary.createUrl().setTransformation(tr).generate("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:

```swift
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.

```swift
let url = cloudinary.createUrl().setTransformation(CLDTransformation()
    .setHeight(150).setWidth(150).setCrop(.crop).setEffect(.sepia).setRadius(20).chain()
    .setOverlayWithLayer(CLDTextLayer()
    .setFontFamily(fontFamily: "Arial").setFontSize(60).setText(text: "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](#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:

```swift
let downloader:CLDDownloader = cloudinary.createDownloader()
let myImage = downloader.fetchImage(url) { (progress) in
    // Handle progress
} completionHandler: { (image, error) in
    // Handle result
}
```

### Image Caching

Caching images on the users device will improve performance when loading your media assets. There are currently three caching mechanisms for caching images with the iOS SDK when using the `CLDImageView` widget or the  `fetchImage` method of the `CLDDownloader` class. The caching mechanism differs based on the SDK version you are using:

* Native URLCache for v5.0.0 and newer
* CLDURLCache for v4.0.0 to 4.7.0 (deprecated)
* CLDImageCachePolicy for versions older then v4.0.0 (deprecated)

#### URLCache

Image caching is handled by the native [URLCache](https://developer.apple.com/documentation/foundation/urlcache) class and provides a simpler implementation to the previous `CLDURLCache`. By default, caching is enabled and images will be cached on both disk and memory after the initial request, such as loading an image into the `CLDImageView` widget.

> **INFO**: `URLCache` is the caching system used in the iOS SDK v5.0.0 and newer and is enabled by default. If you're upgrading from an older version, the caching will be switched and all cached images will need to be re-downloaded. As a result, you may see bandwidth usage increase initially. To disable this, set `cloudinary.enableUrlCache = false`.

#### CLDURLCache 

> **NOTE**: As of v5.0.0 this caching mechanism is deprecated.

The `CLDURLCache` mechanism is a more innovative cache system based on the iOS class [URLCache](https://developer.apple.com/documentation/foundation/urlcache), it stores the response, and verifies attributes of the `cache-control` header, specifically the `max-age` attribute.

> **INFO**: `CLDURLCache` is the caching system used in the iOS SDK v4.0.0 and newer and is enabled by default. If you're upgrading from an older version, the caching will be switched and all cached images will need to be re-downloaded. As a result, you may see bandwidth usage increase initially. To disable this, set `cloudinary.enableUrlCache = false` and re-enable the old cache mechanism by setting `cloudinary.cachePolicy = .disk`.

`CLDURLCache` works by making an initial HTTP request for an image by default and returning the image with a 200 HTTP status code if successful. Once complete, the request will be cached on both disk and memory. From that point on, for every cache hit, the SDK will check if the request has expired (by checking if it has exceeded the max-age attribute). 

If the request has not expired, it is retrieved from the cache. 

If the request has expired, the `if-modified-since` header with the original date of the request received will be sent. One of two responses will be returned based on whether the image has been updated:

* `200` - the image has been updated and the SDK will get the new image and cache the response.
* `304` - the image is unchanged and the SDK will get the image from the cache.

## 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:

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

> **INFO**: :title=Help us improve our SDK

We'd love to hear your thoughts on using our iOS SDK. Please take a moment to complete this [short survey](https://forms.gle/YyUh1gGfuWbBwaKF9). Thanks for your time!

## 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:

* [Resizing and cropping](#resizing_and_cropping)
* [Converting to another image format](#converting_to_another_image_format)
* [Applying image effects and filters](#applying_image_effects_and_filters)
* [Adding text and image overlays](#adding_text_and_image_overlays)
* [Image optimizations](#image_optimizations)

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](image_transformations).
For a full list of all supported image transformations and their usage, see the [Transformation URL API Reference](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:

```swift
let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setWidth(250).setHeight(250).setGravity("faces").setCrop("fill"))
  .generate("family_bench.jpg")
```

Original image

Fill cropping with 'faces' gravity

You can also use automatic gravity to determine what to keep in the crop automatically.

```swift
let url = cloudinary.createUrl()
  .setTransformation(CLDTransformation()
    .setWidth(200).setHeight(300).setGravity("auto").setCrop("fill"))
  .generate("basketball_in_net.jpg")
```

Original image

Fill cropping with 'auto' gravity

For details on all resizing and cropping options, see [resizing and cropping images](resizing_and_cropping).

### 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: 

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

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

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

For more details, see [Image format support](image_transformations#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).

```swift
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](https://res.cloudinary.com/demo/image/upload/e_cartoonify/r_max/e_outline:100,co_lightblue/b_lightblue/h_300/actor.jpg "with_code: false, with_url:false")

For more details on the available image effects and filters, see [Visual image effects and enhancements](effects_and_artistic_enhancements).

### 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 as 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.

```swift
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()
    .setFlags("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](https://res.cloudinary.com/demo/image/upload/w_400,h_250,c_fill,g_south/l_nice_couple,w_1.3,h_1.3,g_faces,c_crop,fl_region_relative/e_saturation:50/e_vignette/fl_layer_apply,w_100,r_max,g_center,y_20,x_-20/l_balloon,h_55/e_hue:-20,a_5/fl_layer_apply,x_30,y_5/l_text:Cookie_40_bold:Love,co_rgb:f08/a_20,fl_layer_apply,x_-45,y_44/c_crop,w_300,h_250,x_30/r_60/coffee_cup.jpg "with_code: false, with_url:false")

### 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 both the `fetchFormat` and `quality` attributes to automatically deliver an image that minimizes file size while meeting the required quality level, and is delivered using the optimal file format for the device or operating system version. In the example below, the automatic format and quality parameters are applied, resulting in a significant file size reduction with no visible change in quality. 

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

![50% file size optimization using the auto quality feature](https://res.cloudinary.com/demo/image/upload/f_auto,q_auto/pond_reflect.jpg "with_code: false, with_url:false, thumb: w_400")

For an in-depth review of the many ways you can optimize your images, see [Image optimization](image_optimization).

## Responsive images

Responsive design is a method of providing an optimal viewing experience to users, tailored to their device, viewport 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 viewport 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](resizing_and_cropping#resize_and_crop_modes) to apply when adjusting the image
* `gravity`: String - the location in the image to be used as the [focus for the transformation](resizing_and_cropping#control_gravity)

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:

```swift      
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:

```swift
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:

```swift
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)
```

