如何从swift中的字节数组创建位图图像
我有一个来自指纹传感器设备的字节数组。我想创建一个位图。我已经尝试了几个例子,但我所得到的只是一个零UIImage。如何从swift中的字节数组创建位图图像
如果有任何步骤可以做到这一点,请告诉我。
谢谢。
这是我的FUNC做:
func didFingerGrabDataReceived(data: [UInt8]) {
if data[0] == 0 {
let width1 = Int16(data[0]) << 8
let finalWidth = Int(Int16(data[1]) | width1)
let height1 = Int16(data[2]) << 8
let finalHeight = Int(Int16(data[3]) | height1)
var finalData:[UInt8] = [UInt8]()
// i dont want the first 8 bytes, so am removing it
for i in 8 ..< data.count {
finalData.append(data[i])
}
dispatch_async(dispatch_get_main_queue()) {() -> Void in
let msgData = NSMutableData(bytes: finalData, length: finalData.count)
let ptr = UnsafeMutablePointer<UInt8>(msgData.mutableBytes)
let colorSpace = CGColorSpaceCreateDeviceGray()
if colorSpace == nil {
self.showToast("color space is nil")
return
}
let bitmapContext = CGBitmapContextCreate(ptr, finalWidth, finalHeight, 8, 4 * finalWidth, colorSpace, CGImageAlphaInfo.Only.rawValue);
if bitmapContext == nil {
self.showToast("context is nil")
return
}
let cgImage=CGBitmapContextCreateImage(bitmapContext);
if cgImage == nil {
self.showToast("image is nil")
return
}
let newimage = UIImage(CGImage: cgImage!)
self.imageViewFinger.image = newimage
}
}
我得到一个扭曲的图像。有人请帮助
这里的一个重要问题是,当你调用CGBitmapContextCreate
时,你指定你正在单独构建一个alpha通道,你的data
缓冲区显然使用每个像素一个字节,但是对于“每行字节数”参数,您已指定4 * width
。它应该是width
。当您捕获每像素四个字节(例如RGBA)时,通常使用4x,但由于缓冲区每像素使用一个字节,因此应删除该4倍因子。
就个人而言,我还告诉了一系列其他方面的改进,即:
应该被分发到主队列的唯一的事情就是控制的UIKit的更新
您可以退休
finalData
,因为您不需要从一个缓冲区复制到另一个缓冲区,而是可以直接构建msgData
。-
你或许应该绕过您自己的缓冲区的建立完全,虽然和调用
CGBitmapContextCreate
与nil
的数据参数,在这种情况下,它会创建自己的缓冲区您可以通过CGBitmapContextGetData
检索。如果你将它传递给一个缓冲区,它假定你将自己管理这个缓冲区,这是我们在这里没有做的。如果您创建自己的缓冲区并且没有正确管理该内存,那么您会在看起来像是有效的情况下遇到难以重现的错误,但是突然间您会看到缓冲区无故崩溃类似的情况。通过让Core Graphics管理内存,可以防止这些问题。
我可能会将该字节缓冲区的转换从更新
UIImageView
的UIImage
中分离出来。
所以能产生类似:
func maskFromData(data: [UInt8]) -> UIImage? {
guard data.count >= 8 else {
print("data too small")
return nil
}
let width = Int(data[1]) | Int(data[0]) << 8
let height = Int(data[3]) | Int(data[2]) << 8
guard data.count >= width * height + 8 else {
print("data not large enough to hold \(width)x\(height)")
return nil
}
guard let colorSpace = CGColorSpaceCreateDeviceGray() else {
print("color space is nil")
return nil
}
guard let bitmapContext = CGBitmapContextCreate(nil, width, height, 8, width, colorSpace, CGImageAlphaInfo.Only.rawValue) else {
print("context is nil")
return nil
}
let dataPointer = UnsafeMutablePointer<UInt8>(CGBitmapContextGetData(bitmapContext))
for index in 0 ..< width * height {
dataPointer[index] = data[index + 8]
}
guard let cgImage = CGBitmapContextCreateImage(bitmapContext) else {
print("image is nil")
return nil
}
return UIImage(CGImage: cgImage)
}
然后
if let image = maskFromData(data) {
dispatch_async(dispatch_get_main_queue()) {
self.imageViewFinger.image = image
}
}
Heyyyyyyy :) :) :)它的工作方式类似于魅力:)非常感谢抢劫:)我不想要第一个8字节,因为它包含宽度,高度和总字节数。所以我忽略它。 –
请重新审视我的疑问句和帮助我。 –
顺便说一句,宽度和高度只占用4个字节,但你跳过前8个字节。我在下面的答案中保留了这个,但我想确保这是你的实际意图,在你跳过的宽度和高度之后有四个字节... – Rob