You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:32:38