从UIImage / CGImage中以数组forms获取像素数据

我有一个应用程序,允许用户在UIImageView元素上自由绘制(如素描垫)。

我想获得原始的RGB像素数据(作为0到255整数值)作为一个multidimensional array,所以我可以喂它到机器学习algorithm。 或者有其他的方法可以将原始图像数据发送到单独的C ++函数吗?

有没有一种简单的方法在Swift中做到这一点?

将CGImage转换为强度值数组

我的函数需要一个CGImage并返回一个无符号的8位整数数组以及图像的宽度和高度。 我写这个代码用于灰度图像。 将其扩展为颜色应该是将灰度更改为RGB,并将每个像素的字节数更改为3(假设没有Alpha通道)。

 func pixelValues(fromCGImage imageRef: CGImage?) -> (pixelValues: [UInt8]?, width: Int, height: Int) { var width = 0 var height = 0 var pixelValues: [UInt8]? if let imageRef = imageRef { width = imageRef.width height = imageRef.height let bitsPerComponent = imageRef.bitsPerComponent let bytesPerRow = imageRef.bytesPerRow let totalBytes = height * bytesPerRow let colorSpace = CGColorSpaceCreateDeviceGray() var intensities = [UInt8](repeating: 0, count: totalBytes) let contextRef = CGContext(data: &intensities, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: 0) contextRef?.draw(imageRef, in: CGRect(x: 0.0, y: 0.0, width: CGFloat(width), height: CGFloat(height))) pixelValues = intensities } return (pixelValues, width, height) } func image(fromPixelValues pixelValues: [UInt8]?, width: Int, height: Int) -> CGImage? { var imageRef: CGImage? if var pixelValues = pixelValues { let bitsPerComponent = 8 let bytesPerPixel = 1 let bitsPerPixel = bytesPerPixel * bitsPerComponent let bytesPerRow = bytesPerPixel * width let totalBytes = height * bytesPerRow imageRef = withUnsafePointer(to: &pixelValues, { ptr -> CGImage? in var imageRef: CGImage? let colorSpaceRef = CGColorSpaceCreateDeviceGray() let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue).union(CGBitmapInfo()) let data = UnsafeRawPointer(ptr.pointee).assumingMemoryBound(to: UInt8.self) let releaseData: CGDataProviderReleaseDataCallback = { (info: UnsafeMutableRawPointer?, data: UnsafeRawPointer, size: Int) -> () in } if let providerRef = CGDataProvider(dataInfo: nil, data: data, size: totalBytes, releaseData: releaseData) { imageRef = CGImage(width: width, height: height, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow: bytesPerRow, space: colorSpaceRef, bitmapInfo: bitmapInfo, provider: providerRef, decode: nil, shouldInterpolate: false, intent: CGColorRenderingIntent.defaultIntent) } return imageRef }) } return imageRef } 

在Swift 3和Swift 4中,使用Core Graphics,可以很容易地做你想做的事情:

 extension UIImage { func pixelData() -> [UInt8]? { let size = self.size let dataSize = size.width * size.height * 4 var pixelData = [UInt8](repeating: 0, count: Int(dataSize)) let colorSpace = CGColorSpaceCreateDeviceRGB() let context = CGContext(data: &pixelData, width: Int(size.width), height: Int(size.height), bitsPerComponent: 8, bytesPerRow: 4 * Int(size.width), space: colorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) guard let cgImage = self.cgImage else { return nil } context?.draw(cgImage, in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) return pixelData } }