Skip to content

Latest commit

 

History

History
133 lines (111 loc) · 6.75 KB

IMAGE.md

File metadata and controls

133 lines (111 loc) · 6.75 KB

Convert

Convert image between multiple formats.

Options

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

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

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

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
])

Mirror and Flip

Reflect image horizontally or vertically.

Usage

ImageSettings(edit: [.mirror, .flip])

Frame Rate adjustment

Set custom animated image frame rate. Will not increase source image frame rate.

Usage

ImageSettings(frameRate: 24)

Info

Extract info without loading an image from file.

Usage

let info = try ImageTool.getInfo(source: url)

Image Frameworks

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.

Frame Processing

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 Format/Encoder

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.