生成vImage.PixelBuffer像素数组后图像出现黑条,求助原因分析
问题:vImage生成的RGB图像出现黑条
我通过vImage.PixelBuffer生成随机RGB像素数组并创建CGImage,但生成的图像存在黑条,代码如下:
import Accelerate let width = 200 let height = 200 var pixelValues = [UInt8](repeating: 0, count: width * height * 3) for i in 0..<pixelValues.count { pixelValues[i] = .random(in: 0...255) } let buffer = vImage.PixelBuffer( pixelValues: pixelValues, size: .init(width: width, height: height), pixelFormat: vImage.Interleaved8x3.self ) let format = vImage_CGImageFormat( bitsPerComponent: 8, bitsPerPixel: 8 * 3, colorSpace: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipLast.rawValue) )! let image = buffer.makeCGImage(cgImageFormat: format)!
生成的图像:
原因及解决方法
核心原因:内存字节对齐问题
CGImage要求图像的每行像素数据必须是4字节对齐的(这是多数系统的内存对齐标准)。你的代码中,图像宽度为200,每行RGB像素的字节数是200*3=600,600不是4的倍数,不符合CGImage的对齐要求。当vImage将像素数据转换为CGImage时,行数据的偏移计算出错,导致后续行的像素位置错位,最终显示出黑条。
解决方法
方法1:调整图像宽度为4的倍数
直接将width改为204(或其他4的倍数),这样每行字节数204*3=612是4的倍数,满足对齐要求。
方法2:手动处理行字节对齐
生成像素数组时,计算符合对齐要求的每行字节数,预留对齐空间,仅填充有效像素部分:
import Accelerate let width = 200 let height = 200 // 计算每行字节数,向上取整到4的倍数 let bytesPerRow = (width * 3 + 3) & ~3 var pixelValues = [UInt8](repeating: 0, count: bytesPerRow * height) // 逐行填充有效像素 for y in 0..<height { for x in 0..<width { let baseIndex = y * bytesPerRow + x * 3 pixelValues[baseIndex] = .random(in: 0...255) pixelValues[baseIndex+1] = .random(in: 0...255) pixelValues[baseIndex+2] = .random(in: 0...255) } } let buffer = vImage.PixelBuffer( pixelValues: pixelValues, size: .init(width: width, height: height), pixelFormat: vImage.Interleaved8x3.self, bytesPerRow: bytesPerRow // 指定对齐后的每行字节数 ) let format = vImage_CGImageFormat( bitsPerComponent: 8, bitsPerPixel: 8 * 3, colorSpace: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipLast.rawValue) )! let image = buffer.makeCGImage(cgImageFormat: format)!
内容的提问来源于stack exchange,提问作者wigging
相关产品推荐
相关产品推荐

