1

我第一次使用 AVCaptureStillImageOutput,我在某个时候保存了 JPEG 图像。我想保存 PNG 图像而不是 JPEG 图像。我需要为此做些什么?

我在应用程序中有这 3 行代码:

let stillImageOutput = AVCaptureStillImageOutput()
stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)

有没有一种简单的方法来修改这些行以获得我想要的?浏览网络后,似乎 anser 是 NO(除非我不够幸运),但我仍然相信一定有一些好的解决方案。

4

2 回答 2

2

AVFoundation Programming Guide中的示例代码展示了如何将 CMSampleBuffer 转换为 UIImage(在Converting CMSampleBuffer to a UIImage Object下)。从那里,您可以使用UIImagePNGRepresentation(image)将其编码为 PNG 数据。

这是该代码的 Swift 翻译:

extension UIImage
{
    // Translated from <https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/06_MediaRepresentations.html#//apple_ref/doc/uid/TP40010188-CH2-SW4>
    convenience init?(fromSampleBuffer sampleBuffer: CMSampleBuffer)
    {
        guard let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil }

        if CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly) != kCVReturnSuccess { return nil }
        defer { CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly) }

        let context = CGBitmapContextCreate(
            CVPixelBufferGetBaseAddress(imageBuffer),
            CVPixelBufferGetWidth(imageBuffer),
            CVPixelBufferGetHeight(imageBuffer),
            8,
            CVPixelBufferGetBytesPerRow(imageBuffer),
            CGColorSpaceCreateDeviceRGB(),
            CGBitmapInfo.ByteOrder32Little.rawValue | CGImageAlphaInfo.PremultipliedFirst.rawValue)

        guard let quartzImage = CGBitmapContextCreateImage(context) else { return nil }
        self.init(CGImage: quartzImage)
    }
}
于 2016-01-05T06:43:44.247 回答
1

这是上述代码的 Swift 4 版本。

extension UIImage
{
    convenience init?(fromSampleBuffer sampleBuffer: CMSampleBuffer)
    {
        guard let imageBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return nil }

        if CVPixelBufferLockBaseAddress(imageBuffer, .readOnly) != kCVReturnSuccess { return nil }
        defer { CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly) }

        let context = CGContext(
        data: CVPixelBufferGetBaseAddress(imageBuffer),
        width: CVPixelBufferGetWidth(imageBuffer),
        height: CVPixelBufferGetHeight(imageBuffer),
        bitsPerComponent: 8,
        bytesPerRow: CVPixelBufferGetBytesPerRow(imageBuffer),
        space: CGColorSpaceCreateDeviceRGB(),
        bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)

        guard let quartzImage = context!.makeImage() else { return nil }
        self.init(cgImage: quartzImage)
    }
}
于 2019-03-09T08:24:09.807 回答