我想使用QTKit.framework将所有帧写入磁盘以进行相机输入。但我得到的所有图像都是半透明的,没有一些颜色,可能是颜色空间问题? ( 它们在预览视图中似乎很好但是当我写它们时“发生了什么”。 我不知道那是什么。
-(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,我也得到了同样的图像,就像图像中缺少一些通道一样,所有写入的帧都有白色背景。 (因为JPEG不允许透明?)
原始和书面(JPEG)一:
(我不显示PNG,因为它是透明的,很难在浏览器中看到)
提前致谢。
答案 0 :(得分:2)
我不确定你的问题是什么,但这是我如何将图像保存到磁盘。只需传入您从委托方法获得的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];
}
答案 1 :(得分:1)
您在实际处理之前解锁图像缓冲区。尝试移动这一行:
CVPixelBufferUnlockBaseAddress(videoFrame,0);
到最后
答案 2 :(得分:1)
我正在做一些有点相似的事情,并且看到同样的问题。我稍微修改了您的代码,并将kCGImageAlphaPremultipliedFirst
更改为kCGImageAlphaNoneSkipFirst
。大概是因为框架不包含alpha,即使它是每像素32位,这也解决了我的问题。