ImageIO is an Apple framework that provides low level access to image files and is what powers UIImage and other image related operations on iOS and macOS. However, in part because it is a C/Core Foundation framework, using it can be difficult.
ImageIO.Swift is a lightweight wrapper around the framework that makes it much easier to access the vast power that ImageIO provides, including animated GIFs, incremental loading and efficient thumbnail generation.
While there are alternatives that provide many of the same features, and many of them use very similar implimentations based on
ImageIO, this project provides a unified interface for all uses of ImageIO. So for instance you can use the same view and image processing code for animated images, progressive jpegs, and any other format that ImageIO supports.
You can think of
CG/NS/UIImage as a single frame of pixels.
ImageSource sits a level below that, providing access to almost anything an image file provides, including metadata and multiple representations. For instance, animated images have multiple image frames as well as timing metadata.
ImageSourceView is provided to display image sources, including animations.
CG/NS/UIImage can only represent a single animation frame from an animated GIF or PNG. ImageSource on the other hand can generate images for each frame of the animation, along with timing data.
To display an animated image, set
isAnimationEnabled = true on an
ImageSourceView. Variable delay times and loop counts will even be taken into account. Implimentation is based off of Apple's sample code and works similarly to FLAnimatedImage, although neither of those support aPNG.
Similar to https://github.com/contentful-labs/Concorde ImageIO actually support incremental loading out of the box. This can be used with progressive JPEGs to show low resolution versions of an image until the rest of the image loads.
Additionally, animated images can load individual frames incrementally as well. If animation is enabled,
ImageSourceView will show the first frame loaded until the entire image loads, at which time the animation will begin normally.
let imageSource = ImageSource.incremental() imageSourceView.imageSource = imageSource // as data is loaded, pass in the entire image data imageSource.update(loadedData, isFinal: loadedData.count == totalCount)
Depending on the underlying image file and the options passed in, you can get an embeded thumnail in an image or a generated thumbnail.
Typically if you are not using the embeded thumbnail from the image, it is better to load a complete image and draw it in a smaller view than it is to generate a thumbnail (🤷🏽♀️), both in terms of time and memory. However if you do need to generate a thumbnail, this method can be quit a bit faster and use a lot less memory than loading the image and drawing into a context.
Because images sources can reference a file on disk, you can load metadata for an image without loading the entire file into memory. This is especially useful for getting an images size.
ImageSource(url: fileURL).properties(at: 0)?.imageSize
Note that if the image source is being loaded incrementally or references an invalid file, the size will be nil.
To run the example project, clone the repo, and run
pod install from the Example directory first.
In Xcode 11 you can add ImageIOSwift as a package in your project settings using the Github URL of the project.
On macOS, you can use is on the command line by adding the following to your Package.swift:
dependencies: [ .package(url: "https://github.com/davbeck/ImageIOSwift.git", from: "0.5.0"), ],
Note that because ImageIO is not available on Linux (or any non-Apple platform) that this package cannot be used there.
Add the following line to your Podfile:
ImageIOSwift is available under the MIT license. See the LICENSE file for more info.