在swift中从UIImage / CGImage获取像素数据作为数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在swift中从UIImage / CGImage获取像素数据作为数组相关的知识,希望对你有一定的参考价值。
到目前为止,我有一个应用程序允许用户在UIImageView
元素上自由绘制(如草图板)。
我想将原始RGB像素数据(作为0
到255
整数值)作为多维数组获取,因此我可以将其输入到机器学习算法中。或者是否有其他方法可以将原始图像数据发送到单独的C ++函数?
在Swift中有一个简单的方法吗?
答案
Converting a CGImage to an array of intensity values
我的函数接受一个CGImage
并返回一个无符号8位整数数组以及图像的宽度和高度。我写了这段代码用于灰度图像。将其扩展为颜色应该是将Gray更改为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
}
}
以上是关于在swift中从UIImage / CGImage获取像素数据作为数组的主要内容,如果未能解决你的问题,请参考以下文章
UIImage 与 CGImage 的 Swift 等价物?
来自 UIImage 或来自文件的 vImage - Swift 和 Accelerate 框架
Re: 快速从 UIImage/CGImage 获取像素数据作为数组
如何在 Swift beta 3 中从 UIImagePickerControllerDelegate 获取 UIImage?