通常需要从图像获取像素数据或从像素数据重建该图像。如何拍摄图像,将其转换为像素值数组,然后使用Swift
中的像素数组使用CoreGraphics
重建图像?
这个问题的答案的质量已经到处都是,所以我想要一个规范的答案。
答案 0 :(得分:5)
此功能可以轻松扩展为彩色图像。为简单起见,我使用的是灰度,但我已经对这些更改进行了评论,以获得RGB。
func pixelValuesFromImage(imageRef: CGImage?) -> (pixelValues: [UInt8]?, width: Int, height: Int)
{
var width = 0
var height = 0
var pixelValues: [UInt8]?
if let imageRef = imageRef {
width = CGImageGetWidth(imageRef)
height = CGImageGetHeight(imageRef)
let bitsPerComponent = CGImageGetBitsPerComponent(imageRef)
let bytesPerRow = CGImageGetBytesPerRow(imageRef)
let totalBytes = height * bytesPerRow
let colorSpace = CGColorSpaceCreateDeviceGray()
pixelValues = [UInt8](count: totalBytes, repeatedValue: 0)
let contextRef = CGBitmapContextCreate(&pixelValues!, width, height, bitsPerComponent, bytesPerRow, colorSpace, 0)
CGContextDrawImage(contextRef, CGRectMake(0.0, 0.0, CGFloat(width), CGFloat(height)), imageRef)
}
return (pixelValues, width, height)
}
我将一个图像(在这种情况下为每像素8位灰度)重建为CGImage
。
func imageFromPixelValues(pixelValues: [UInt8]?, width: Int, height: Int) -> CGImage?
{
var imageRef: CGImage?
if let pixelValues = pixelValues {
let bitsPerComponent = 8
let bytesPerPixel = 1
let bitsPerPixel = bytesPerPixel * bitsPerComponent
let bytesPerRow = bytesPerPixel * width
let totalBytes = height * bytesPerRow
let providerRef = CGDataProviderCreateWithData(nil, pixelValues, totalBytes, nil)
let colorSpaceRef = CGColorSpaceCreateDeviceGray()
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.None.rawValue)
.union(.ByteOrderDefault)
imageRef = CGImageCreate(width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
providerRef,
nil,
false,
CGColorRenderingIntent.RenderingIntentDefault)
}
return imageRef
}
您需要将图像复制到Playground的Resources文件夹中,然后在下面更改文件名和扩展名以匹配。最后一行的结果是从CGImage构造的UIImage。
var image: UIImage? = nil
let URL = NSBundle.mainBundle().URLForResource("zebra_5", withExtension: "tif")
if let path = URL?.path {
if NSFileManager().fileExistsAtPath(path) {
do {
try NSData(contentsOfURL: URL!, options: .DataReadingMappedIfSafe)
} catch let error as NSError {
print ("Error: \(error.localizedDescription)")
}
image = UIImage(contentsOfFile: path)
}
}
let (intensityValues, width, height) = pixelValuesFromImage(image?.CGImage)
let roundTrippedImage = imageFromPixelValues(intensityValues, width: width, height: height)
let zebra = UIImage(CGImage: roundTrippedImage!)
答案 1 :(得分:0)
我无法让上面的Cameron代码正常工作,所以我想测试另一种方法。我发现Vacawama's code,它依赖于ARGB像素。您可以使用该解决方案,只需将每个灰度值映射到每个灰度值即可将其转换为ARGB值:
msbuild -p:RestorePackagesConfig=true -t:restore;build