我想将一个yuv 420SP图像(直接从相机,YCbCr格式捕获)转换为iOS中的jpg。我发现的是CGImageCreate()函数https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGImage/Reference/reference.html#//apple_ref/doc/uid/TP30000956-CH1g-F17167,它接受一些参数,包括包含的字节数组,并且应该返回一些CGImage,当输入到UIImageJPEGRepresentation()时,其UIImage返回jpeg数据,但实际上并没有发生 输出图像数据远非所需。至少输出不是零。
作为CGImageCreate()的输入,我将每个组件的位设置为4,每像素位为12,以及一些默认值。
真的可以转换yuv YCbCr图片广告不仅仅是rgb吗?如果是,那么我认为我在CGImageCreate函数的输入值中做错了。
答案 0 :(得分:0)
从我可以看到的here,CGColorSpaceRef colorspace
参数只能引用RGB,CMYK或灰度。
所以我认为首先需要将YCbCr420图像转换为RGB,例如,使用IPP函数YCbCr420toRGB
(doc)。或者,您可以编写自己的转换例程,但并不难。
答案 1 :(得分:0)
以下是转换captureOutput:didOutputSampleBuffer:fromConnection
AVVideoDataOutput
方法返回的样本缓冲区的代码:
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
GLubyte *rawImageBytes = CVPixelBufferGetBaseAddress(pixelBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer); //2560 == (640 * 4)
size_t bufferWidth = CVPixelBufferGetWidth(pixelBuffer);
size_t bufferHeight = CVPixelBufferGetHeight(pixelBuffer); //480
size_t dataSize = CVPixelBufferGetDataSize(pixelBuffer); //1_228_808 = (2560 * 480) + 8
CGColorSpaceRef defaultRGBColorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rawImageBytes, bufferWidth, bufferHeight, 8, bytesPerRow, defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGImageRef image = CGBitmapContextCreateImage(context);
CFMutableDataRef imageData = CFDataCreateMutable(NULL, 0);
CGImageDestinationRef destination = CGImageDestinationCreateWithData(imageData, kUTTypeJPEG, 1, NULL);
NSDictionary *properties = @{(__bridge id)kCGImageDestinationLossyCompressionQuality: @(0.25),
(__bridge id)kCGImageDestinationBackgroundColor: (__bridge id)CLEAR_COLOR,
(__bridge id)kCGImageDestinationOptimizeColorForSharing : @(TRUE)
};
CGImageDestinationAddImage(destination, image, (__bridge CFDictionaryRef)properties);
if (!CGImageDestinationFinalize(destination))
{
CFRelease(imageData);
imageData = NULL;
}
CFRelease(destination);
UIImage *frame = [[UIImage alloc] initWithCGImage:image];
CGContextRelease(context);
CGImageRelease(image);
renderFrame([self.childViewControllers.lastObject.view viewWithTag:1].layer, frame);
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}
以下是像素格式类型的三个选项:
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
kCVPixelFormatType_32BGRA
如果_captureOutput
是我的AVVideoDataOutput
实例的指针引用,则设置像素格式类型的方式如下:
[_captureOutput setVideoSettings:@{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}];