cocoa - 将 CVImageBufferRef 转换为 PNG

标签 cocoa macos png cgimage qtkit

我想使用 QTKit.framework 将所有帧写入磁盘以进行相机输入。但我得到的所有图像都是半透明的并且没有一些颜色,也许是色彩空间问题? ;( 它们在预览 View 中看起来不错,但是当我编写它们时,“某些事情”发生了。 我想知道那是什么。

-(void)savePNGImage:(CGImageRef)imageRef path:(NSString *)path {
    NSURL *outURL = [[NSURL alloc] initFileURLWithPath:path]; 
    CGImageDestinationRef dr = CGImageDestinationCreateWithURL ((CFURLRef)outURL, (CFStringRef)@"public.png" , 1, NULL);
    CGImageDestinationAddImage(dr, imageRef, NULL);
    CGImageDestinationFinalize(dr);
    [outURL release];
}
-(void)saveJPEGImage:(CGImageRef)imageRef path:(NSString *)path {
    CFMutableDictionaryRef mSaveMetaAndOpts = CFDictionaryCreateMutable(nil, 0,
                                                                    &kCFTypeDictionaryKeyCallBacks,  &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(mSaveMetaAndOpts, kCGImageDestinationLossyCompressionQuality, 
                         [NSNumber numberWithFloat:1.0]);   // set the compression quality here
    NSURL *outURL = [[NSURL alloc] initFileURLWithPath:path];
    CGImageDestinationRef dr = CGImageDestinationCreateWithURL ((CFURLRef)outURL, (CFStringRef)@"public.jpeg" , 1, NULL);
    CGImageDestinationAddImage(dr, imageRef, mSaveMetaAndOpts);
    CGImageDestinationFinalize(dr);
    [outURL release];
}


- (void)captureOutput:(QTCaptureOutput *)captureOutput 
  didOutputVideoFrame:(CVImageBufferRef)videoFrame 
     withSampleBuffer:(QTSampleBuffer *)sampleBuffer 
       fromConnection:(QTCaptureConnection *)connection{

    CVPixelBufferLockBaseAddress(videoFrame,0); 
    uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(videoFrame); 
    size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoFrame); 
    size_t width = CVPixelBufferGetWidth(videoFrame); 
    size_t height = CVPixelBufferGetHeight(videoFrame); 
    CVPixelBufferUnlockBaseAddress(videoFrame,0);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef newContext = CGBitmapContextCreate(baseAddress, 
                                                        width, height, 8, 
                                                        bytesPerRow, 
                                                        colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 
        CGImageRef frame = CGBitmapContextCreateImage(newContext); 

    CGContextRelease(newContext); 
    CGColorSpaceRelease(colorSpace);

    [self savePNGImage:frame path:[NSString stringWithFormat:@"/Users/nacho4d/Desktop/framesCam/frame%003d.png", frameNum++]];
[self saveJPEGImage:frame path:[NSString stringWithFormat:@"/Users/nacho4d/Desktop/framesCam/frame%003d.jpeg", frameNum++]];

    CGImageRelease(frame);
}

Capturer 属性只是帧大小和像素格式,如下所示: [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32ARGB], (id)kCVPixelBufferPixelFormatTypeKey

更新:

我也尝试过使用 JPEG,并且得到了相同类型的图像,就像图像中缺少一些 channel ,并且所有写入的帧都有白色背景。 (因为 JPEG 不允许透明??)

原件和书面(JPEG)一张:

alt text alt text (我没有显示 PNG,因为它是透明的并且很难在浏览器中看到)

提前致谢。

最佳答案

我不确定您的问题是什么,但这是我将图像保存到磁盘的方法。只需传递您从委托(delegate)方法中获得的 CVImageBufferRef,当然还有您自己的 URL,它应该可以正常工作。至少对我来说是这样。祝你好运!

-(void)saveImage:(CVImageBufferRef)image toURL:(NSURL*)url{

    NSCIImageRep *imageRep = [NSCIImageRep imageRepWithCIImage:[CIImage imageWithCVImageBuffer:image]];

    NSImage *_image = [[NSImage alloc] initWithSize:[imageRep size]];
    [_image addRepresentation:imageRep];

    NSData *bitmapData = [_image TIFFRep    resentation];
    NSBitmapImageRep *bitmapRep = [NSBitmapImageRep imageRepWithData:bitmapData];
    NSData *imageData = [bitmapRep representationUsingType:NSJPEGFileType properties:nil];

    [_image release];
    _image = [[NSImage alloc] initWithData:imageData];

    NSBitmapImageRep *imgRep = [[_image representations] objectAtIndex: 0];
    NSData *data = [imgRep representationUsingType: NSPNGFileType properties: nil];
    [data writeToFile: [self getSaveString] atomically: NO];

    [_image release];
}

关于cocoa - 将 CVImageBufferRef 转换为 PNG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4014396/

相关文章:

cocoa-touch - 输出西类牙语字符

objective-c - NSDictionary countForKey

macos - 如何从主机上的docker exec的pid检索docker容器名称(MacOS)

swift - 如何使用Swift跨平台编写png图片

python - 如何使用 Python Wand/ImageMagick 将 PSD 转换为 PNG?

php - 在 .htaccess 上用一些参数将 php 重写为 png

objective-c - 核心数据中没有默认值的可选(数字)属性 - 为什么不鼓励使用它们?

cocoa - 从 NSView 检索 CGImage

c++ - 非法指令 4 在 Mac 上使用 C++

python - Golang net.Listen 绑定(bind)到已在使用的端口