【发布时间】:2021-09-26 23:20:32
【问题描述】:
我的目标是从 CVImageBuffer(相机流)中提取 300x300 像素帧并将其转换为 UInt 字节数组。从技术上讲,数组大小应该是 90,000。但是,我得到了更大的价值。任何帮助将不胜感激发现错误。
将Image缓冲区转换为UIImage的方法
func getImageFromSampleBuffer(image_buffer : CVImageBuffer?) -> UIImage?
{
if let imageBuffer = image_buffer {
// Lock the base address of the pixel buffer
CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags.readOnly);
// Get the number of bytes per row for the pixel buffer
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
// Get the number of bytes per row for the pixel buffer
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
// Get the pixel buffer width and height
let width = CVPixelBufferGetWidth(imageBuffer);
let height = CVPixelBufferGetHeight(imageBuffer);
// Create a device-dependent RGB color space
let colorSpace = CGColorSpaceCreateDeviceRGB();
// Create a bitmap graphics context with the sample buffer data
var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Little.rawValue
bitmapInfo |= CGImageAlphaInfo.premultipliedFirst.rawValue & CGBitmapInfo.alphaInfoMask.rawValue
//let bitmapInfo: UInt32 = CGBitmapInfo.alphaInfoMask.rawValue
let context = CGContext.init(data: baseAddress, width: width, height: height, bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo)
// Create a Quartz image from the pixel data in the bitmap graphics context
let quartzImage = context?.makeImage();
// Unlock the pixel buffer
CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags.readOnly);
// Create an image object from the Quartz image
let image = UIImage.init(cgImage: quartzImage!);
return (image);
}
return nil
}
}
将图像数据转换为 UInt8 数组的扩展
extension Data {
func toByteArray() -> [UInt8]? {
var byteData = [UInt8](repeating:0, count: self.count)
self.copyBytes(to: &byteData, count: self.count)
return byteData
}
}
代码的使用
let image = getImageFromSampleBuffer(image_buffer: imageBuffer)
//Issue*******
if let byteArrayOfImage = image.copy(newSize: CGSize(width: 300, height: 300))?.pngData()?.toByteArray(){
print(byteArrayOfImage.count) // Technically should print 90,000. However it prints a large value
}
我错过了什么
【问题讨论】:
-
pngData() 函数不返回像素数据。它返回一个 PNG 文件的数据,包括 PNG 文件头和压缩的像素数据,这与您的预期完全不同。正如其他答案中提到的,如果您的图像大小为 300x300,这并不意味着它应该有 90000 个字节,因为 1 个像素很可能需要 4 个字节的未压缩格式(如果这是 RGBA)。
标签: swift swift5 cvpixelbuffer