如何将 UIImage 转换为 CVPixelBuffer [重复]

问题描述 投票:0回答:1

Apple 的新 CoreML 框架具有采用

CVPixelBuffer
的预测功能。为了对
UIImage
进行分类,必须在两者之间进行转换。

我从苹果工程师那里得到的转换代码:

1  // image has been defined earlier
2
3     var pixelbuffer: CVPixelBuffer? = nil
4   
5     CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_OneComponent8, nil, &pixelbuffer)
6     CVPixelBufferLockBaseAddress(pixelbuffer!, CVPixelBufferLockFlags(rawValue:0))
7   
8     let colorspace = CGColorSpaceCreateDeviceGray()
9     let bitmapContext = CGContext(data: CVPixelBufferGetBaseAddress(pixelbuffer!), width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelbuffer!), space: colorspace, bitmapInfo: 0)!
10  
11    bitmapContext.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))

此解决方案速度很快,适用于灰度图像。根据图像类型必须进行的更改是:

  • 5号线 |
    kCVPixelFormatType_OneComponent8
    到另一个
    OSType
    kCVPixelFormatType_32ARGB
    对于 RGB)
  • 8号线 |
    colorSpace
    到另一个
    CGColorSpace
    CGColorSpaceCreateDeviceRGB
    对于 RGB)
  • 9号线 |
    bitsPerComponent
    为内存每个像素的位数(RGB 为 32)
  • 9号线 |
    bitmapInfo
    为非零
    CGBitmapInfo
    属性(
    kCGBitmapByteOrderDefault
    是默认值)
swift uiimage cvpixelbuffer coreml
1个回答
50
投票

你可以看一下这个教程https://www.hackingwithswift.com/whats-new-in-ios-11,代码是Swift 4

func buffer(from image: UIImage) -> CVPixelBuffer? {
  let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
  var pixelBuffer : CVPixelBuffer?
  let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
  guard (status == kCVReturnSuccess) else {
    return nil
  }

  CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
  let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)

  let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
  let context = CGContext(data: pixelData, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: image?.cgImage?.bitsPerComponent ?? 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)

  context?.translateBy(x: 0, y: image.size.height)
  context?.scaleBy(x: 1.0, y: -1.0)

  UIGraphicsPushContext(context!)
  image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
  UIGraphicsPopContext()
  CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))

  return pixelBuffer
}
© www.soinside.com 2019 - 2024. All rights reserved.