Giter VIP home page Giter VIP logo

swim's Introduction

Swim

Cross platform image library for Swift.

API

Generic Image type

struct Image<P: PixelType, T: DataType>

Supported types

PixelType: Gray, GrayAlpha, RGB, RGBA, ARGB
DataType: Bool, UInt8, Int, Float, Double, Complex<T: BinaryFloatingPoint>

Some functions assume pixel values are:

  • in [0, 255] range if DataType is integer.
  • in [0, 1] range if DataType is floating point.

Creation

let image = Image<RGBA, UInt8>(width: 3, height: 5, data: uint8Array)

// Can use type inference
let gray = Image(width: 3, height: 20, gray: intArray)
let rgb = Image(width: 4, height: 5, rgb: floatArray)
let rgba = Image(width: 3, height: 5, rgba: doubleArray)
let argb = Image(width: 5, height: 3, argb: uint8Array)

// Filled with values/colors
let zero = Image<RGBA, Double>(width: 3, height: 4, value: 0)
let red = Image<RGBA, Double>(width: 3, height: 5, color: Color(r: 1, g: 0, b: 0, a: 1))

Input and output

For reading and writing image, Swim uses stb_image.h and stb_image_write.h.

Reading & writing files

let image = try Image<RGBA, UInt8>(contentsOf: url)
try image.write(to: dstPath)

Reading & writing Data

let data = try Data(contentsOf: url)
let image = try Image<RGB, UInt8>(fileData: data)
let jpegData = try image.fileData(format: .jpeg(quality: 80))

Platform specific operations

let image = try! Image<RGBA, UInt8>(contentsOf: url)

// on macOS
let nsImage = image.nsImage()
let imageFromNS = Image<RGBA, UInt8>(nsImage: nsImage)!

// on iOS
let uiImage = image.uiImage()
let imageFromUI = Image<RGBA, UInt8>(uiImage: uiImage)!

// with vImage
var argb = image.toARGB()
let kernel = Filter<UInt8>.mean(size: 5)
        
let blurred: Image<ARGB, UInt8> = try vImageUtils.createImageWithBuffer(width: argb.width, height: argb.height) { dest in
    try vImageUtils.withBuffer(image: &argb) { argb in
        try kernel.withUnsafeBufferPointer { kernel in
            let flags: vImageProcessingFlag = [.edgeExtend,
                                                .printDiagnosticsToConsole]
            let code = vImageConvolve_ARGB8888(&argb, &dest, nil, 0, 0, kernel.baseAddress, 5, 5, nil, flags.vImage_Flags)
            try vImageUtils.validateErrorCode(code)
        }
    }
}

// on Swift for TensorFlow
let tensor = Tensor(image: image)

Subscriptions

Pixel manipulation

let image = try Image<RGBA, UInt8>(contentsOf: url)
let color: Color<RGBA, UInt8> = image[0, 0]
let red: UInt8 = image[0, 0, 0] // red channel of (x: 0, y: 0)
let red2: UInt8 = image[0, 0, .red] // ditto
let red3: UInt8 = image[0, 0][.red] // ditto

image[1, 0] += 1 // Add 1 for each channel
image[1, 0, .green] += 1 // Add 1 for Green channel

Subimage

let image = try Image<RGBA, UInt8>(contentsOf: url)
let sub1: Image<RGBA, UInt8> = image[0..<100, 0..<100]
let sub2: Image<RGBA, UInt8> = image[rows: 0..<100]
image[col: 2] += 1

Channel extraction

let image = try Image<RGBA, UInt8>(contentsOf: url)
let red: Image<Gray, UInt8> = image[channel: 0]
image[channel: .blue] += 1

Conversion

let image = try Image<RGB, Float>(contentsOf: url)

// to gray scale
let gray1: Image<Gray, Float> = image.toGray() // with default weights
let gray2: Image<Gray, Float> = image.toGray(wr: 1/3, wg: 1/3, wb: 1/3) // with specified weights

// type conversion
let doubleImage1: Image<RGB, Double> = image.cast()
let doubleImage2 = image.cast(to: Double.self) // ditto

// pixel conversion
let redOnlyRGBA: Image<RGBA, Float> = image.pixelwiseConverted { src, dst in 
    dst[.red] = src[.red]
    dst[.green] = 0
    dst[.blue] = 0
    dst[.alpha] = 1
}

Drawing

var image = try Image<RGB, Float>(contentsOf: url)

image.drawLine((0, 0), (100, 120), color: Color(r: 1, g: 0, b: 0))
image.drawRect(10..<20, 30..<50, color: .green)
image.drawCircle(center: (50, 50), radius: 30, color: .blue)

image.drawImage(origin: (80, 80), rgbImage) // simply overwrites
image.drawImage(origin: (200, 200), rgbaImage) // with alpha blending

let font = try! TrueTypeFont(url: URL(fileURLWithPath: "/System/Library/Fonts/Helvetica.ttc"), 
                             fontSize: 30)
image.drawText(origin: (100, 100),
               text: "TEXT DRAWING", 
               font: font, 
               color: .black)

For font rendering, Swim uses stb_truetype.h.

Resize

let image = try Image<RGB, Float>(contentsOf: url)
let resizedBL = image.resize(width: 512, height: 512) // default .bilinear
let resizedNN = image.resize(width: 512, height: 512, method: .nearestNeighbor)
let resizedBC = image.resize(width: 512, height: 512, method: .bicubic)
let resizedAA = image.resize(width: 512, height: 512, method: .areaAverage)

Example: NearestNeighbor / Bilinear / Bicubic / Lanczos2 / Lanczos3 / Area Average

resize

Warp

let image = try Image<RGBA, Double>(contentsOf: url)
let affine = AffineTransformation<Double>(scale: (1, 1.5), rotation: .pi/6. translation: (100, 120))
// `edgeMode` specifies how to fill pixels outside the base image.
let interpolator = BilinearInterpolator<RGBA, Double>(edgeMode: .edge)
let warpedImage = image.warp(transformation: affine, outputSize: (500, 500), interpolator: interpolator)

Example: NN+Wrap / BL+Constant / BC+Reflect / Lanczos2+Edge / Lanczos3+Symmetric

warp

Compare images

let image1 = try Image<Gray, Double>(contentsOf: url1)
let image2 = try Image<Gray, Double>(contentsOf: url2)

let ssd = ImageCompare.ssd(image1, image2)
let sad = ImageCompare.sad(image1, image2)
let ncc = ImageCompare.ncc(image1, image2)
let zncc = ImageCompare.zncc(image1, image2)
let psnr = ImageCompare.psnr(image1, image2)
let ssim = ImageCompare.ssim(image1, image2, windowSize: 7)

Blending

var bottomImage = try Image<RGB, Float>(contentsOf: url1)
let topimage = try Image<RGB, Float>(contentsOf: url2)

bottomImage(image: topImage, mode: .multiply)
bottomImage(image: topImage, mode: .additive)
bottomImage(image: topImage, mode: .screen)
bottomImage(image: topImage, mode: .overlay)

Example: Multiply / Additive / Screen / Overlay

blend

Integral image

let image = try Image<Gray, Float>(contentsOf: url)
let integral = IntegralImageConverter.convert(image: image)

Convolution/Filter

let image = try Image<Gray, Float>(contentsOf: url)
let blur = image.convoluted(Filter.gaussian3x3)
let maximum = image.rankFilter(.maximum, windowSize: 3)
let bilateral = image.bilateralFilter(windowSize: 5, distanceSigma: 1, valueSigma: 0.1)
let nlmean = image.nonLocalMeanFilter(windowSize: 5, distance: 2, sigma: 0.1)

Example: Gaussian x10 / Bilateral x5 / Emboss / Sobel(Horizontal) / Laplacian

filter

Fast Fourier transformation

let image = try Image<Gray, Double>(contentsOf: url)
// image size must be power of 2
let transformed: Image<Gray, Complex<Double>> = FourierTransformer.fft(image: image)
let inverted: Image<Gray, Double> = FourierTransformer.ifft(image: transformed)

Example: Spectrum and inverted image / Low-pass filtered / High-pass filtered

fft

Histogram equalization

var image = try Image<Gray, Double>(contentsOf: url)
Histograms.equalize(image: &image)

Example: Before / After

hist

Bayer filter

let image = try Image<RGB, Float>(contentsOf: url)
let converter = BayerConverter(pattern: .bggr)
let bayer = converter.convert(image: image)
let reconstruct = converter.demosaic(image: bayer)

Example: Base / Bayer format / Reconstructed

bayer_bggr

Application examples

VisualTests contains more examples (works only on macOS).

License

The MIT License

swim's People

Contributors

serhii-londar avatar t-ae avatar ungast avatar vojtamolda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

swim's Issues

TensorFlow dependency has a version incompatibility on macOS

Thanks for putting this library together, we're looking at using it in the near term to perform image loading and saving within Swift for TensorFlow's models (pending PR for this ).

One issue we encountered is that if you attempt to build the current version of the library on macOS via SwiftPM, you will hit a version mismatch. By default, SwiftPM targets macOS 10.10, but we needed to set a minimum macOS version of 10.13 for Swift for TensorFlow. This causes a problem when building with one of our toolchains on macOS, triggering an error here.

To enable the import of TensorFlow in this project on macOS, I believe you'll need to add

    platforms: [
        .macOS(.v10_13),
    ],

just after the package name in Package.swift. One downside of this is that it will limit your backwards compatibility on macOS to 10.13.

In the meantime, I've pegged our import of Swim to 3.6.1, the release before the TensorFlow extensions were added. With that, we can use this framework, but I wanted to point this out for future commits.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.