koher/swift-image

SwiftImage: an image library in Swift with Swifty APIs and value semantics


Keywords
image, image-processing, swift
License
MIT

Documentation

EasyImagy

EasyImagy makes it easy to handle images in Swift.

var image = Image<RGBA>(named: "ImageName")!

print(image[x, y])
image[x, y] = RGBA(red: 255, green: 0, blue: 0, alpha: 127)
image[x, y] = RGBA(0xFF00007F) // red: 255, green: 0, blue: 0, alpha: 127

// Iterates over all pixels
for pixel in image {
    // ...
}

// Converts the image (e.g. binarizations)
let binarized: Image<RGBA> = image.map { $0.gray < 128 ? .black : .white }

// From/to `UIImage`
image = Image<RGBA>(uiImage: imageView.image!)!
imageView.image = image.uiImage

Introduction

Handling images by CoreGraphics is too complicated: various formats, old C APIs and painful memory management. EasyImagy provides the easier way to handle images in exchange for some performance.

Typically Images in EasyImagy are used with RGBA. RGBA is a simple structure declared as follows.

struct RGBA {
    var red: UInt8
    var green: UInt8
    var blue: UInt8
    var alpha: UInt8
}

You can access to a pixel easily using subscripts like image[x, y] and its channels by properties red, green, blue and alpha.

Image and RGBA also provide some convenient methods and properties to make it easy to process images. For example, it is possible to convert an image to grayscale combining Image#map with RGBA#gray in one line as shown below.

let result = image.map { $0.gray }

Usage

Import

import EasyImagy

Initialization

let image = Image<RGBA>(named: "ImageName")!
let image = Image<RGBA>(contentsOfFile: "path/to/file")!
let image = Image<RGBA>(data: NSData(/* ... */))!
let image = Image<RGBA>(uiImage: imageView.image!)!
let image = Image<RGBA>(width: 640, height: 480, pixel: .black) // a black image
let image = Image<RGBA>(width: 640, height: 480, pixels: pixels)

Access to a pixel

// Gets a pixel by subscripts
let pixel = image[x, y]
// Sets a pixel by subscripts
image[x, y] = RGBA(0xFF0000FF)
image[x, y].alpha = 127
// Safe get for a pixel
if let pixel = image.pixel(x, y) {
    print(pixel.red)
    print(pixel.green)
    print(pixel.blue)
    print(pixel.alpha)

    print(pixel.gray) // (red + green + blue) / 3
    print(pixel) // formatted like "#FF0000FF"
} else {
    // `pixel` is safe: `nil` is returned when out of bounds
    print("Out of bounds")
}

Iteration

for pixel in image {
    ...
}

Rotation

let result = image.rotate() // Rotate clockwise
let result = image.rotate(-1) // Rotate counterclockwise
let result = image.rotate(2) // Rotate by 180 degrees

Flip

let result = image.flipX() // Flip Horizontally
let result = image.flipY() // Flip Vertically

Resizing

let result = image.resize(width: 100, height: 100)
let result = image.resize(width: 100, height: 100,
    interpolationQuality: kCGInterpolationNone) // Nearest neighbor

Crop

Slicing is done with no copy cost.

let slice: ImageSlice<RGBA> = image[32..<64, 32..<64] // no copy cost
let cropped = Image<RGBA>(slice) // copy is done here

Conversion

Image can be converted by map as well as Array. Followings are the examples.

Grayscale

let result: Image<UInt8> = image.map { (pixel: Pixel) -> Pixel in
    pixel.gray
}
// Shortened form
let result = image.map { $0.gray }

Binarization

let result = image.map { (pixel: Pixel) -> Pixel in
    pixel.gray < 128 ? Pixel.black : Pixel.white
}
// Shortened form
let result = image.map { $0.gray < 128 ? .black : .white }

Binarization (auto threshold)

let threshold = UInt8(image.reduce(0) { $0 + $1.grayInt } / image.count)
let result = image.map { $0.gray < threshold ? .black : .white }

Mean filter

let kernel = Image<Float>(width: 3, height: 3, pixel: 1.0 / 9.0)
let result = image.convoluted(kernel)

Gaussian filter

let kernel = Image<Int>(width: 5, height: 5, pixels: [
    1,  4,  6,  4, 1,
    4, 16, 24, 16, 4,
    6, 24, 36, 24, 6,
    4, 16, 24, 16, 4,
    1,  4,  6,  4, 1,
]).map { Float($0) / 256.0 }
let result = image.convoluted(kernel)

With UIImage

From UIImage

let image = Image<RGBA>(uiImage: imageView.image!)!

To UIImage

imageView.image = image.uiImage

Installation

Carthage

Carthage is available to install EasyImagy. Add it to your Cartfile:

github "koher/EasyImagy" "master"

Manually

For iOS 8 or later,

  1. Put EasyImagy.xcodeproj into your project/workspace in Xcode.
  2. Click your project icon and select the application target and the "General" tab.
  3. Add EasyImagy.framework to "Embedded Binaries".
  4. import EasyImagy in your swift files.

License

The MIT License