Convert image between multiple formats.
Image converter takes the following parameters:
Parameter | Description | Values | Default |
---|---|---|---|
Image format | Output image format | HEIF , HEIF10 , HEIC , HEICS , PNG , GIF , JPEG , TIFF , BMP , JPEG2000 , ICO |
Format extracted from destination path or from the source image |
Image size | Output image size to fit in or cropping options | original - Original image size is used.fit(CGSize) - Scale image to fit in.crop(Crop) - Crop image based on options |
.original |
Image quality | Image quality in range from 0.0 to 1.0, ignored by lossless formats | [0.0, 1.0] |
1.0 |
Frame rate | Output animated image frame rate, ignored by static image formats | Int? |
nil - equals to original |
Skip Animation | May be used for converting animated image sequence into static image | Boolean |
false |
Preserve Alpha channel | Preserve or drop alpha channel from image | Boolean |
true |
Embed thumbnail | Embed image thumbnail into output file | Boolean |
false |
Optimized color | Optimize image colors for sharing | Boolean |
false |
Background color | Used by image formats without alpha channel or when preserveAlphaChannel is true |
CGColor? |
nil |
Edit | Image operations | Set<ImageOperation> |
empty |
Image Framework | Preferred framework to use for image processing | .ciImage , .cgImage , .vImage |
.ciImage |
Usage
ImageSettings(
format: .png,
size: .fit(.fhd),
quality: 0.75,
frameRate: 24,
skipAnimation: false,
preserveAlphaChannel: true,
embedThumbnail: false,
optimizeColorForSharing: false,
backgroundColor: .white,
edit: [
// rotate, flip, mirror and other image operations goes here
],
preferredFramework: .vImage
)
Resize image while preserving aspect ratio. Provide CGSize
resolution for image to fit it. Width and height may be rounded to nearest even number.
Predefined resolutions are SD
, HD
, Full HD
, Ultra HD
which are accessible via CGSize
extension.
Usage
ImageSettings(size: .fit(.fhd))
ImageSettings(size: .fit(CGSize(width: 720, height: 720)))
Crop the image. There are three initializers which at the end produce CGRect
for cropping.
Usage
ImageSettings(size: .crop(options: .init(size: CGSize(width: 720, height: 720), aligment: .center)))
ImageSettings(size: .crop(options: .init(origin: CGPoint(x: 256, y: 256), size: CGSize(width: 1080, height: 1080))))
// Crop and scale to fit
ImageSettings(size: .crop(fit: .fhd, options: .init(size: CGSize(width: 512, height: 512), aligment: .center)))
Rotate an image. There are three fill options (for non-90 degree multiply angles) - crop, color or blur. Blur is not available using CGImage
framework. Transparent color replaced with black on unsupported image formats.
Showcase
starfield_animation.heif rotated by 30 degree with blurred extend | rally_burst.heic rotated by 10 degree with blurred extend |
iphone_13.heic rotated by 30 with blurred extend | iphone_x.heic rotated by 45 and with blurred extend using vImage |
starkdev.png rotated by 45 with transparent color extend | iphone_x.jpg rotated by 30 and cropped to fill |
Usage
ImageSettings(edit: [
.rotate(.angle(.clockwise)) // rotate by 90 degree
.rotate(.angle(.pi/4)) // rotate by 45 degree and crop the edges
.rotate(.angle(.pi/4), fill: .blur(kernel: 55)) // rotate by 45 degree with blurred extend on edges
.rotate(.angle(.pi/4), fill: .color(alpha: 255, red: 255, green: 255, blue: 255)) // rotate by 45 degree with white color fill on edges
])
Reflect image horizontally or vertically.
Usage
ImageSettings(edit: [.mirror, .flip])
Set custom animated image frame rate. Will not increase source image frame rate.
Usage
ImageSettings(frameRate: 24)
Extract info without loading an image from file.
Usage
let info = try ImageTool.getInfo(source: url)
Three image frameworks are capable to execute the same image operations. The choice of framework is based on preferredFramework
parameter and supported by framework image formats. For example CIImage
cannot load animated image from file, so will fallback to CGImage
.
Based on image format and settings the CIImage
or CGImage
is used internally, that exact type is available via imageProcessing
callback. For example, static HDR image is proceed using CIImage
framework, so the CGImage
in ImageProcessor
will be nil, and you only need to pass the proceed CIImage
back. Index is helpful for animated images. The next code will scale image by 4X:
ImageSettings(edit: [
.imageProcessing { ciImage, cgImage, orientation, index in
if let ciImage = ciImage {
let resized = ciImage.resizing(to: CGSize(width: ciImage.extent.width * 4.0, height: ciImage.extent.height * 4.0))
return (resized, cgImage)
} else if let cgImage = cgImage {
let resized = cgImage.resizing(to: CGSize(width: cgImage.width * 4, height: cgImage.height * 4)) ?? cgImage
return (ciImage, resized)
} else {
return (ciImage, cgImage)
}
}
])
Custom image encoder should implement CustomImageFormat
protocol and be registered using ImageFormat.registerCustomFormat(SomeCustomImageFormat())
. Custom image encoder receives the final image and is responsible for writing encoded data to the file at provided url.