ios - 将 UIImage 转换为 8-Gray 类型的像素缓冲区

标签 ios swift uiimage cvpixelbuffer coreml

我能够将 UIImage 转换为 ARGB CVPixelBuffer,但现在我正在尝试将 UIImage 转换为灰度一个缓冲区。 我以为自从代码通过以来我就拥有了它,但是 coreML 模型提示说:

"Error Domain=com.apple.CoreML Code=1 "Image is not expected type 8-Gray, instead is Unsupported (40)"

这是我目前拥有的灰度 CGContext:

public func pixelBufferGray(width: Int, height: Int) -> CVPixelBuffer? {

        var pixelBuffer : CVPixelBuffer?
        let attributes = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]

        let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height), kCVPixelFormatType_8IndexedGray_WhiteIsZero, attributes as CFDictionary, &pixelBuffer)

        guard status == kCVReturnSuccess, let imageBuffer = pixelBuffer else {
            return nil
        }

        CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))

        let imageData =  CVPixelBufferGetBaseAddress(imageBuffer)

        guard let context = CGContext(data: imageData, width: Int(width), height:Int(height),
                                      bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(imageBuffer),
                                      space: CGColorSpaceCreateDeviceGray(),
                                      bitmapInfo: CGImageAlphaInfo.none.rawValue) else {
                                        return nil
        }

        context.translateBy(x: 0, y: CGFloat(height))
        context.scaleBy(x: 1, y: -1)

        UIGraphicsPushContext(context)
        self.draw(in: CGRect(x:0, y:0, width: width, height: height) )
        UIGraphicsPopContext()
        CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))

        return imageBuffer

    }

任何帮助将不胜感激

最佳答案

即使图像称为灰度,正确的像素格式是:kCVPixelFormatType_OneComponent8


希望这个完整的代码片段能对其他人有所帮助:

public func pixelBufferGray(width: Int, height: Int) -> CVPixelBuffer? {

        var pixelBuffer : CVPixelBuffer?
        let attributes = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]

        let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(width), Int(height), kCVPixelFormatType_OneComponent8, attributes as CFDictionary, &pixelBuffer)

        guard status == kCVReturnSuccess, let imageBuffer = pixelBuffer else {
            return nil
        }

        CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))

        let imageData =  CVPixelBufferGetBaseAddress(imageBuffer)

        guard let context = CGContext(data: imageData, width: Int(width), height:Int(height),
                                      bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(imageBuffer),
                                      space: CGColorSpaceCreateDeviceGray(),
                                      bitmapInfo: CGImageAlphaInfo.none.rawValue) else {
                                        return nil
        }

        context.translateBy(x: 0, y: CGFloat(height))
        context.scaleBy(x: 1, y: -1)

        UIGraphicsPushContext(context)
        self.draw(in: CGRect(x:0, y:0, width: width, height: height) )
        UIGraphicsPopContext()
        CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0))

        return imageBuffer

    }

关于ios - 将 UIImage 转换为 8-Gray 类型的像素缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44530203/

相关文章:

ios - 如何判断 UIImage 是彩色还是单色?

ios - 如何只用一台 iPhone/iPad 测试新功能 AirDrop?

ios - 允许英文和阿拉伯数字输入 UITextField swift

ios - jazzy 的 Xcode 集成脚本,Swift 项目的文档生成器

iphone - 为 UIimage 添加边框

iPhone PNG 加载 alpha 伪影

ios - 在 Objective C 中打印一个变量

ios - 我如何在 MKmapView 中拖动我的注释,就像 Google Pin Drop 和 Dragging :iOS

objective-c - 适用于 iOS 的 Facebook SDK 问题

arrays - 一项一项地返回数组中的项目,直到返回所有项目,然后重新开始