首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用vImage_Buffer管理像素并创建图像?

如何使用vImage_Buffer管理像素并创建图像?
EN

Stack Overflow用户
提问于 2022-08-01 21:53:58
回答 1查看 172关注 0票数 0

我希望将图像定义为数组中的RGB(A)值,然后使用vImage_buffer生成CG/UI映像。

有一个Pixel_8888数据类型((UInt8, UInt8, UInt8, UInt8)的别名)似乎是一个很有前途的数据类型。是这样的吗?

到目前为止,我从数组[Pixel_8888]开始,并使用.withUnsafeMutableBytes创建了一个vImage_Buffer,它给了我一个条纹图像。

但是,如果没有条带(即显示每个RGBA通道),我就无法生成图像。

我认为从RGBA到平面转换需要一个步骤,但我可能错了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-02 12:03:00

苹果公司刚刚在vImage_Buffer上推出了一个快速友好的包装器,名为vImage.PixelBuffer,可以让你的生活更轻松。

多通道vImage缓冲区中的底层数据通常是交错的.这意味着,对于RGB,像素存储红色,绿色,蓝色,红色,绿色,蓝色等。

下面的代码演示如何使用vImage.PixelBuffer创建一个非常简单的梯度。代码创建一个新的缓冲区,然后访问它的数据以写入红色、绿色和蓝色像素值。最后,代码创建一个CGImage

代码语言:javascript
复制
let buffer = vImage.PixelBuffer<vImage.Interleaved8x4>(
    size: .init(width: 640, height: 480)
)

buffer.withUnsafeMutableBufferPointer { bufferPtr in
    for x in 0 ..< buffer.width  {
        for y in 0 ..< buffer.height {
         
            let rowBytes = (buffer.rowStride * buffer.byteCountPerPixel)
            let index = y*rowBytes + x*buffer.channelCount
            
            let red = Pixel_8(Float(x) / Float(buffer.width) * 255)
            let blue = Pixel_8(Float(y) / Float(buffer.height) * 255)
            
            bufferPtr[index + 0] = red
            bufferPtr[index + 1] = 0 // green
            bufferPtr[index + 2] = blue
            bufferPtr[index + 3] = 0 // alpha
        }
    }
}

let format = vImage_CGImageFormat(bitsPerComponent: 8,
                               bitsPerPixel: 8 * 4,
                               colorSpace: CGColorSpaceCreateDeviceRGB(),
                               bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.noneSkipLast.rawValue))!

let image = buffer.makeCGImage(cgImageFormat: format)

生成的图像如下:

下面是使用现有API的相同代码:

代码语言:javascript
复制
let buffer = try! vImage_Buffer(width: 640,
                                height: 480,
                                bitsPerPixel: 8 * 3)

let bufferPtr = buffer.data.assumingMemoryBound(to: Pixel_8.self)

for x in 0 ..< Int(buffer.width) {
    for y in 0 ..< Int(buffer.height) {
        
        let index = y*buffer.rowBytes + x*3
        
        let red = Pixel_8(Float(x) / Float(buffer.width) * 255)
        let blue = Pixel_8(Float(y) / Float(buffer.height) * 255)
        
        bufferPtr[index + 0] = red
        bufferPtr[index + 1] = 0 // green
        bufferPtr[index + 2] = blue
    }
}


let format = vImage_CGImageFormat(bitsPerComponent: 8,
                               bitsPerPixel: 8 * 3,
                               colorSpace: CGColorSpaceCreateDeviceRGB(),
                               bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue))!

let image = try! buffer.createCGImage(format: format)

buffer.free()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73199980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档