【问题标题】:UIImage obtaining CVPixelBuffer Removes AlphaUIImage 获取 CVPixelBuffer 移除 Alpha
【发布时间】:2019-12-11 23:50:41
【问题描述】:

下面的函数接受一个UIImage 并从UIImage 返回一个CVPixelBuffer,但它删除了alpha 通道。

class func pixelBufferFromImage(image: UIImage, pixelBufferPool: CVPixelBufferPool, size: CGSize) -> CVPixelBuffer {

        var pixelBufferOut: CVPixelBuffer?

        let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &pixelBufferOut)
        if status != kCVReturnSuccess {
            fatalError("CVPixelBufferPoolCreatePixelBuffer() failed")
        }

        let pixelBuffer = pixelBufferOut!

        CVPixelBufferLockBaseAddress(pixelBuffer, [])

        let data = CVPixelBufferGetBaseAddress(pixelBuffer)
        let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
        let context = CGContext(data: data, width: Int(size.width), height: Int(size.height),
                                bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue)

        context!.clear(CGRect(x: 0, y: 0, width: size.width, height: size.height))

        let horizontalRatio = size.width / image.size.width
        let verticalRatio = size.height / image.size.height
        //aspectRatio = max(horizontalRatio, verticalRatio) // ScaleAspectFill
        let aspectRatio = min(horizontalRatio, verticalRatio) // ScaleAspectFit

        let newSize = CGSize(width: image.size.width * aspectRatio, height: image.size.height * aspectRatio)

        let x = newSize.width < size.width ? (size.width - newSize.width) / 2 : 0
        let y = newSize.height < size.height ? (size.height - newSize.height) / 2 : 0

        context!.draw(image.cgImage!, in: CGRect(x: x, y: y, width: newSize.width, height: newSize.height))


        CVPixelBufferUnlockBaseAddress(pixelBuffer, [])

        return pixelBuffer
    }
  1. 我知道初始图像有一些带有特定alpha = 0 的像素,因为如果我这样做po image.pixelColor(atLocation: CGPoint(x: 0, y: 0)) 它会打印出来

可选 - 一些:UIExtendedSRGBColorSpace 0 0 0 0

但生成的图像有黑色背景。

我也尝试使用CGImageAlphaInfo.premultipliedLast.rawValue,但这会导致图像为蓝色,因此我假设RGBAARGB 正在交换。但是,具有讽刺意味的是,这意味着 ARGB 中的 B 是 255,这表明 RGBA 中的 A 将是 255,它应该是 0。

在使用CGContext 时,如何正确地将UIImage alpha 转换为CVPixelBuffer

编辑 1:

这是我的pixelBufferPool 的代码。

func createPixelBufferAdaptor() {
            let pixelFormatRGBA = kCVPixelFormatType_32RGBA //Fails
            let pixelFormatARGB = kCVPixelFormatType_32ARGB //Works
            let sourcePixelBufferAttributesDictionary = [
                kCVPixelBufferPixelFormatTypeKey as String: NSNumber(value: pixelFormatARGB),
                kCVPixelBufferWidthKey as String: NSNumber(value: Float(renderSettings.width)),
                kCVPixelBufferHeightKey as String: NSNumber(value: Float(renderSettings.height))
            ]
            pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: videoWriterInput,
                                                                      sourcePixelBufferAttributes: sourcePixelBufferAttributesDictionary)
        }

它只在我使用kCVPixelFormatType_32ARGB 时有效。我所说的工作是指当我尝试使用缓冲池时

let status = CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &pixelBufferOut)
        if status != kCVReturnSuccess {
            fatalError("CVPixelBufferPoolCreatePixelBuffer() failed")
        }

如果我使用 RGBA 版本,这将失败,但如果我使用 ARGB 版本,则可以。

【问题讨论】:

  • 请附上代码如何创建pixelBufferPool。您是否在属性中将键 kCVPixelBufferPixelFormatTypeKey 传递为 kCVPixelFormatType_32RGBA
  • 我不是。我使用 kCVPixelFormatType_32ARGB which makes sense why my A` 将是 255,但没有意义,因为我的照片中确实有蓝色,B 应该是 0。尽管如此,我试图切换到 RGBA 来测试我的理论,它会崩溃。上面的Edit 1 描述了会发生什么。谢谢!

标签: ios swift alpha cgcontext cvpixelbuffer


【解决方案1】:

好吧,遗憾的是,我对这个主题的范围太窄了(讽刺的是,因为大多数问题都被认为太宽泛了)。

我试图从AVCaptureSession 旁边的AVAssetWriter 创建一个视频,其中一些图像有一个深度图,然后我会生成它以将一些像素变成清晰的颜色。好吧,通过一些研究,我发现对于图像并显示它们,alpha 通道是保持不变的。但是,对于视频来说,这是不可能的。

How do you play a video with alpha channel using AVFoundation? https://andreygordeev.com/2017/07/01/video-with-transparent-background-ios/ https://github.com/aframevr/aframe/issues/3205 https://www.reddit.com/r/swift/comments/3cw4le/is_it_possible_to_play_a_video_with_an_alpha/

任何人,我的下一个目标是按照一些答案的描述做一个ChromaKey - 要么是应用到我的特征的深度图的掩蔽。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-24
    • 2013-02-07
    • 2020-06-03
    • 2017-10-26
    • 2014-02-20
    • 2017-11-09
    • 1970-01-01
    • 2023-02-14
    相关资源
    最近更新 更多