Documentation/Nuke.docc/Customization/ImageFormats/supported-image-formats.md
Nuke has built-in support for basic image formats like jpeg, png, and heif. It also has the infrastructure for supporting a variety of custom image formats.
Nuke is capable of driving progressive decoding, animated image rendering, progressive animated image rendering, drawing vector images directly or converting them to bitmaps, parsing thumbnails included in the image containers, and more.
All image formats natively supported by the platform are also supported by Nuke, including PNG, TIFF, JPEG, GIF, BMP, ICO, CUR, XBM, HEIF, and WebP (iOS 14+).
You can use the basic UIImageView/NSImageView/WKInterfaceImage to render the images of any of the natively supported formats.
Decoding
ImageDecoders/Default supports progressive JPEG via CGImageSourceCreateIncremental. When ImagePipeline/Configuration-swift.struct/isProgressiveDecodingEnabled is true, the pipeline produces previews as data arrives.
By default, progressive previews are only enabled for progressive JPEGs and GIFs (ImagePipeline/PreviewPolicy). Baseline JPEGs, PNGs, and other formats produce no previews unless explicitly configured via ImagePipeline/Delegate/previewPolicy(for:pipeline:).
For progressive JPEGs with large EXIF headers where CGImageSourceCreateIncremental fails to produce incremental previews, the decoder automatically falls back to generating a thumbnail from the available data.
Encoding
None.
Rendering
To render progressive JPEG, you can use the basic UIImageView/NSImageView/WKInterfaceImage. The default image view loading extensions also support displaying progressive previews.
Decoding
ImageDecoders/Default supports HEIF.
Encoding
ImageEncoders/Default supports HEIF but doesn't use it by default. To enable it, use ImageEncoders/Default/isHEIFPreferred.
You can use ImageEncoders/ImageIO directly:
let image: UIImage
let encoder = ImageEncoders.ImageIO(type: .heif, compressionRatio: 0.8)
let data = encoder.encode(image: image)
Rendering
To render HEIF images, you can use UIImageView/NSImageView/WKInterfaceImage.
Decoding
ImageDecoders/Default automatically recognizes GIFs. It creates an image container (ImageContainer) with the first frame of the GIF as a placeholder and attaches the original image data to the container so that you can perform just-in-time decoding at rendering time.
Encoding
None.
Rendering
To render animated GIFs, please consider using one of the open-source GIF rendering engines, like Gifu, FLAnimatedImage, or other.
Gifu Example
/// A custom image view that supports downloading and displaying animated images.
final class ImageView: UIView {
private let imageView: GIFImageView
private let spinner: UIActivityIndicatorView
private var task: ImageTask?
/* Initializers skipped */
func setImage(with url: URL) {
prepareForReuse()
if let response = ImagePipeline.shared.cache[url] {
imageView.display(response: response)
if !response.isPreview {
return
}
}
spinner.startAnimating()
task = ImagePipeline.shared.loadImage(with: url) { [weak self] result in
self?.spinner.stopAnimating()
if case let .success(response) = result {
self?.imageView.display(response: response)
}
}
}
private func display(response: ImageResponse) {
if let data = response.container.data {
animate(withGIFData: data)
} else {
image = response.image
}
}
private func prepareForReuse() {
task?.cancel()
spinner.stopAnimating()
imageView.prepareForReuse()
}
}
To see this code in action, check out the demo project.
GIFis not the most efficient format for transferring and displaying animated images. Consider using short videos instead. You can find a PoC available in the demo project that uses Nuke to load, cache and display anMP4video.
Decoding
There is currently no built-in support for SVG. Use ImageDecoders/Empty to pass the original image data to an SVG-enabled view and render it using an external mechanism.
Encoding
None.
Rendering
To render SVG, consider using SwiftSVG, SVG, or other frameworks. Here is an example of SwiftSVG rendering vector images.
ImageDecoderRegistry.shared.register { context in
// Replace this with whatever works for you. There are no magic numbers
// for SVG like are used for other binary formats, it's just XML.
let isSVG = context.urlResponse?.url?.absoluteString.hasSuffix(".svg") ?? false
return isSVG ? ImageDecoders.Empty() : nil
}
let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/9/9d/Swift_logo.svg")
ImagePipeline.shared.loadImage(with: url) { [weak self] result in
guard let self, let data = try? result.get().container.data else {
return
}
// You can render an image using whatever size you want, vector!
let targetBounds = CGRect(origin: .zero, size: CGSize(width: 300, height: 300))
let svgView = UIView(SVGData: data) { layer in
layer.fillColor = UIColor.orange.cgColor
layer.resizeToFit(targetBounds)
}
self.view.addSubview(svgView)
svgView.bounds = targetBounds
svgView.center = self.view.center
}
Important: Both SwiftSVG and SVG only support a subset of SVG features.
WebP is supported natively on macOS 11+, iOS 14+, and watchOS 7+ via Image I/O. No additional plugins are required.