2016-07-06 74 views
1

我有一个来自指纹传感器设备的字节数组。我想创建一个位图。我已经尝试了几个例子,但我所得到的只是一个零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 
     } 
} 

我得到一个扭曲的图像。有人请帮助

+0

请重新审视我的疑问句和帮助我。 –

+0

顺便说一句,宽度和高度只占用4个字节,但你跳过前8个字节。我在下面的答案中保留了这个,但我想确保这是你的实际意图,在你跳过的宽度和高度之后有四个字节... – Rob

回答

3

这里的一个重要问题是,当你调用CGBitmapContextCreate时,你指定你正在单独构建一个alpha通道,你的data缓冲区显然使用每个像素一个字节,但是对于“每行字节数”参数,您已指定4 * width。它应该是width。当您捕获每像素四个字节(例如RGBA)时,通常使用4x,但由于缓冲区每像素使用一个字节,因此应删除该4倍因子。


就个人而言,我还告诉了一系列其他方面的改进,即:

  • 应该被分发到主队列的唯一的事情就是控制的UIKit的更新

  • 您可以退休finalData,因为您不需要从一个缓冲区复制到另一个缓冲区,而是可以直接构建msgData

  • 你或许应该绕过您自己的缓冲区的建立完全,虽然和调用CGBitmapContextCreatenil的数据参数,在这种情况下,它会创建自己的缓冲区您可以通过CGBitmapContextGetData检索。如果你将它传递给一个缓冲区,它假定你将自己管理这个缓冲区,这是我们在这里没有做的。

    如果您创建自己的缓冲区并且没有正确管理该内存,那么您会在看起来像是有效的情况下遇到难以重现的错误,但是突然间您会看到缓冲区无故崩溃类似的情况。通过让Core Graphics管理内存,可以防止这些问题。

  • 我可能会将该字节缓冲区的转换从更新UIImageViewUIImage中分离出来。

所以能产生类似:

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 
    } 
} 
+0

Heyyyyyyy :) :) :)它的工作方式类似于魅力:)非常感谢抢劫:)我不想要第一个8字节,因为它包含宽度,高度和总字节数。所以我忽略它。 –

相关问题