[英]CVPixelBuffer resulting into garbage image on the device, while working as expected on the simulator
I am trying to create an image out of artificially created data and want to use CVPixelBuffer
: 我试图用人工创建的数据创建一个图像,并想使用CVPixelBuffer
:
private func RGBAImage(width w: Int, height h: Int) -> UIImage? {
let width = w * Int(UIScreen.main.scale)
let height = h * Int(UIScreen.main.scale)
// Prepare artificial data
let dataPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: width * height * 4)
for i in 0..<width {
for j in 0..<height {
dataPtr[4 * (i + j * width)] = UInt8(sin(Double(i) * 0.01 * .pi / Double(UIScreen.main.scale)) * 127 + 127)
dataPtr[4 * (i + j * width) + 1] = UInt8(255)
dataPtr[4 * (i + j * width) + 2] = UInt8(0)
dataPtr[4 * (i + j * width) + 3] = UInt8(0)
}
}
// Convert data into CVPixelBuffer
var pxBuffer: CVPixelBuffer?
CVPixelBufferCreateWithBytes(
kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32ARGB,
dataPtr,
width * 4,
nil,
nil,
[kCVPixelBufferIOSurfacePropertiesKey: [:]] as CFDictionary,
&pxBuffer
)
dataPtr.deallocate()
guard let cvPxBuffer = pxBuffer else {
return nil
}
// Generate image from CVPixelBuffer
let ciImage = CIImage(cvImageBuffer: cvPxBuffer)
return UIImage(ciImage: ciImage, scale: UIScreen.main.scale, orientation: .up)
}
The code works fine on simulator and shows as this : 代码在模拟器上工作正常并显示如下:
But the same code shows garbage results on the device : 但是相同的代码显示设备上的垃圾结果:
What am I missing here? 我在这里错过了什么? Any suggestion is welcome. 任何建议都是受欢迎的。
Figured out myself. 弄清楚自己。 I still don't know why CVPixelBufferCreateWithBytes
doesn't work, but I was able to make it work by creating the pixel buffer with CVPixelBufferCreate
and setting value of each RGB address one by one. 我仍然不知道为什么CVPixelBufferCreateWithBytes
不起作用,但我能够通过使用CVPixelBufferCreate
创建像素缓冲区并CVPixelBufferCreate
设置每个RGB地址的值来使其工作。 This should be a better approach as well since I don't need to create an array first. 这应该是一个更好的方法,因为我不需要先创建一个数组。
Here is the working code for both device and simulator: 这是设备和模拟器的工作代码:
private func RGBAImage(width w: Int, height h: Int) -> UIImage? {
let width = w * Int(UIScreen.main.scale)
let height = h * Int(UIScreen.main.scale)
let bytesPerPixel = 4
// Create CVPixelBuffer with artificial data
var pxBuffer: CVPixelBuffer?
CVPixelBufferCreate(
kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32ARGB,
nil,
&pxBuffer)
guard let cvPxBuffer = pxBuffer else {
return nil
}
CVPixelBufferLockBaseAddress(cvPxBuffer, CVPixelBufferLockFlags(rawValue: 0))
let bufferWidth = Int(CVPixelBufferGetWidth(cvPxBuffer))
let bufferHeight = Int(CVPixelBufferGetHeight(cvPxBuffer))
let bytesPerRow = CVPixelBufferGetBytesPerRow(cvPxBuffer)
guard let baseAddress = CVPixelBufferGetBaseAddress(pxBuffer!) else {
return nil
}
for row in 0..<bufferHeight {
var pixel = baseAddress + row * bytesPerRow
for col in 0..<bufferWidth {
let alpha = pixel
alpha.storeBytes(of: UInt8(sin(Double(col) * 0.01 * .pi / Double(UIScreen.main.scale)) * 127 + 127), as: UInt8.self)
let red = pixel + 1
red.storeBytes(of: 255, as: UInt8.self)
let green = pixel + 2
green.storeBytes(of: 0, as: UInt8.self)
let blue = pixel + 3
blue.storeBytes(of: 0, as: UInt8.self)
pixel += bytesPerPixel;
}
}
CVPixelBufferUnlockBaseAddress(cvPxBuffer, CVPixelBufferLockFlags(rawValue: 0))
// Generate image from CVPixelBuffer
let ciImage = CIImage(cvImageBuffer: cvPxBuffer)
return UIImage(ciImage: ciImage, scale: UIScreen.main.scale, orientation: .up)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.