UIImage object is a high-level interface for displaying image data in iOS. We can create UIImage objects from files, NSData, Quartz image objects. So this is a class that we come into contact with a lot.

Immutability of UIImage

UIImage object is immutable, so once it’s created, we can’t change its properties. This means that we can only provide property values in the initialization method or depending on the image itself. Again, because it is immutable, it is safe to use in any thread.

If we want to change some properties of the UIImage object, we can create a copy of the image using convenience methods and custom parameter values.

In addition, since UIImage objects are immutable, it does not provide access to the underlying image data. But we can use the UIImagePNGRepresentation or UIImageJPEGRepresentation method to obtain the data contains PNG or JPG format NSData objects. The following code looks like this:

Create a UIImage object

For a UIImage object, there are mainly the following data sources:

Files: We can use the init(contentsOfFile:) method to create objects from the specified file.

Pure Image Data (NSData) : If you have the raw data of the image (represented as an NSData object) in memory, you can create it using init(data:). Note that this method will cache object image data.

CGImage object: if we have a CGImage object, you can use the init (CGImage:) or init (CGImage: scale: create UIImage object orientation:).

CIImage object: if we have a CIImage object, you can use the init (CIImage:) or init (CIImage: scale: create UIImage object orientation:).

It is important to note that if you create UIImage objects from files or pure image data, the corresponding image format should be the image type supported by the system.

For Objective-C, UIImage objects also provide convenience class methods corresponding to these initialization methods to create objects.

Memory management

In practical applications, especially in image applications, we may need to use a large number of images. As we all know, images are usually very memory intensive. If a large number of images are loaded at the same time, it can take up a lot of system memory.

To this end, Apple has adopted a clever strategy. In the case of low memory, the system forces to clear the image data pointed to by the UIImage object to free up some memory. Note that this cleanup only affects the image data, not the UIImage object itself. When we need to draw UIImage objects whose image data has been cleaned, the object will automatically reload the data from the source file. Of course, this is a time-for-space strategy that incurs certain performance costs.

At this point, we have to mention the init(named:) method. This is probably the method that we use the most to create UIImage objects. This method is basically a shortcut to create images using files in the bundle. There are a few things to note about this approach:

Cache: This method first checks the system cache to see if there is an image with a corresponding image name. If so, return the image in the cache; If not, the method loads the image from disk or from the Asset Catalog and returns it, while caching the image to the system. Cached images are released only when a memory warning is received. Therefore, if images are used infrequently, the imageWithContentsOfFile: method can be used to load images, which can reduce memory resource consumption. Of course, this is a trade-off, as reading and writing to disks is also a performance drain, and memory on high-end machines is now too large.

Multi-resolution Image Processing: After iOS 4.0, this method will find images of the corresponding size based on the screen resolution. That is, when we use it, we only need to write the name of the image, and we don’t need to specify whether it is 1x, 2x or 3x, the method will decide for itself.

PNG image suffixes: After iOS 4.0, if the image is in PNG format, the image file name does not need to have an extension.

Thread-safe: This method was not thread-safe prior to iOS 9.0, and calling it in a secondary thread could cause a crash. After iOS 9.0, Apple optimized it to be thread-safe. To avoid unnecessary trouble, try to call this method on the main thread.

This method uses a UIEdgeInsets to specify the top, bottom, left, and right widths or heights that do not distort. It will return a new image. If the image is stretched, the stretched area in the middle is tiled.

Image size limits

The size of UIImage objects should be smaller than 1024 x 1024. Because such large images consume too much memory, problems can arise when using them as maps in OpenGL or when drawing them into view/ Layer. There is no such limitation if the operation is only at the code level. For example, resize a picture larger than 1024*1024 by drawing it into the context of a point map graph. In fact, we need to do this to resize the image to draw it into the view.

Supported image formats

The image formats supported by UIImage are listed in UIImage Class Reference for direct Reference.

One thing to note is that BMP files in RGB-565 format are converted to ARGB-1555 format when loaded.