AVCaptureStillImageOutput.pngStillImageNSDataRepresentation?
Я впервые работаю с AVCaptureStillImageOutput, в какой-то момент я сохраняю изображение JPEG. Вместо изображения в формате JPEG я хотел бы сохранить изображение в формате PNG. Что мне нужно для этого сделать?
У меня есть эти 3 строки кода вдоль приложения:
let stillImageOutput = AVCaptureStillImageOutput()
stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer)
Есть ли простой способ изменить эти строки, чтобы получить то, что я хочу? После просмотра сети кажется, что ответ - НЕТ (если только мне не повезло), тем не менее, я все еще верю, что должно быть какое-то хорошее решение.
1 ответ
В руководстве по программированию AVFoundation приведен пример кода, в котором показано, как преобразовать CMSampleBuffer в UIImage (в разделе " Преобразование CMSampleBuffer в объект UIImage"). Оттуда вы можете использовать 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)
}
}
Вот 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)
}
}