Here are the Swift 2.3 and Swift 3.0 versions of the ColorCubeHelper class.
// | |
// ColorCubeHelper.swift | |
// | |
// Created by Joshua Sullivan on 10/01/16. | |
// Copyright © 2016 Joshua Sullivan. All rights reserved. | |
// | |
import UIKit | |
import Accelerate | |
public final class ColorCubeHelper { | |
public enum ColorCubeError: ErrorType { | |
case IncorrectImageSize | |
case MissingImageData | |
case UnableToCreateDataProvider | |
} | |
public static func createColorCubeData(inputImage image: UIImage, cubeDimension: Int) throws -> NSData { | |
// Set up some variables for calculating memory size. | |
let imageSize = image.size | |
let dim = Int(imageSize.width) | |
let pixels = dim * dim | |
let channels = 4 | |
// If the number of pixels doesn't match what's needed for the supplied cube dimension, abort. | |
guard pixels == cubeDimension * cubeDimension * cubeDimension else { | |
throw ColorCubeError.IncorrectImageSize | |
} | |
// We don't need a sizeof() because uint_8t is explicitly 1 byte. | |
let memSize = pixels * channels | |
// Get the UIImage's backing CGImageRef | |
guard let img = image.CGImage else { | |
throw ColorCubeError.MissingImageData | |
} | |
// Get a reference to the CGImage's data provider. | |
guard let inProvider = CGImageGetDataProvider(img) else { | |
throw ColorCubeError.UnableToCreateDataProvider | |
} | |
let inBitmapData = CGDataProviderCopyData(inProvider) | |
let inBuffer = CFDataGetBytePtr(inBitmapData) | |
// Calculate the size of the float buffer and allocate it. | |
let floatSize = memSize * sizeof(Float.self) | |
let finalBuffer = unsafeBitCast(malloc(floatSize), UnsafeMutablePointer<Float>.self) | |
// Convert the uint_8t to float. Note: a uint of 255 will convert to 255.0f. | |
vDSP_vfltu8(inBuffer, 1, finalBuffer, 1, UInt(memSize)) | |
// Divide each float by 255.0 to get the 0-1 range we are looking for. | |
var divisor = Float(255.0) | |
vDSP_vsdiv(finalBuffer, 1, &divisor, finalBuffer, 1, UInt(memSize)) | |
// Don't copy the bytes, just have the NSData take ownership of the buffer. | |
let cubeData = NSData(bytesNoCopy: finalBuffer, length: floatSize, freeWhenDone: true) | |
return cubeData | |
} | |
} |
// | |
// ColorCubeHelper.swift | |
// | |
// Created by Joshua Sullivan on 10/10/16. | |
// Copyright © 2016 Joshua Sullivan. All rights reserved. | |
// | |
import UIKit | |
import Accelerate | |
public class ColorCubeHelper { | |
public enum ColorCubeError: Error { | |
case incorrectImageSize | |
case missingImageData | |
case unableToCreateDataProvider | |
case unableToGetBitmpaDataBuffer | |
} | |
public static func createColorCubeData(inputImage image: UIImage, cubeDimension: Int) throws -> Data { | |
// Set up some variables for calculating memory size. | |
let imageSize = image.size | |
let dim = Int(imageSize.width) | |
let pixels = dim * dim | |
let channels = 4 | |
// If the number of pixels doesn't match what's needed for the supplied cube dimension, abort. | |
guard pixels == cubeDimension * cubeDimension * cubeDimension else { | |
throw ColorCubeError.incorrectImageSize | |
} | |
// We don't need a sizeof() because uint_8t is explicitly 1 byte. | |
let memSize = pixels * channels | |
// Get the UIImage's backing CGImageRef | |
guard let img = image.cgImage else { | |
throw ColorCubeError.missingImageData | |
} | |
// Get a reference to the CGImage's data provider. | |
guard let inProvider = img.dataProvider else { | |
throw ColorCubeError.unableToCreateDataProvider | |
} | |
let inBitmapData = inProvider.data | |
guard let inBuffer = CFDataGetBytePtr(inBitmapData) else { | |
throw ColorCubeError.unableToGetBitmpaDataBuffer | |
} | |
// Calculate the size of the float buffer and allocate it. | |
let floatSize = memSize * MemoryLayout<Float>.size | |
let finalBuffer = unsafeBitCast(malloc(floatSize), to:UnsafeMutablePointer<Float>.self) | |
// Convert the uint_8t to float. Note: a uint of 255 will convert to 255.0f. | |
vDSP_vfltu8(inBuffer, 1, finalBuffer, 1, UInt(memSize)) | |
// Divide each float by 255.0 to get the 0-1 range we are looking for. | |
var divisor = Float(255.0) | |
vDSP_vsdiv(finalBuffer, 1, &divisor, finalBuffer, 1, UInt(memSize)) | |
// Don't copy the bytes, just have the NSData take ownership of the buffer. | |
let cubeData = NSData(bytesNoCopy: finalBuffer, length: floatSize, freeWhenDone: true) | |
return cubeData as Data | |
} | |
} |
guard let colorCubeImage = UIImage(named: "MyColorEffect-64.png") else { | |
preconditionFailure("Couldn't load the cube data image.") | |
} | |
do { | |
let data = try ColorCubeHelper.createColorCubeData(inputImage: colorCubeImage, cubeDimension: 64) | |
let params: [String : Any] = [ "inputCubeData" : data ] | |
let filter = CIFilter(name: "CIColorCube", withInputParameters: params) | |
// Now you can use the filter. | |
} catch { | |
debugPrint("Unable to create cube data: \(error)") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment