2013-10-22 80 views
2

我已经使用AVFoundation构建了一个摄像头。将NSData转换为CGImage,然后返回NSData使文件太大

一旦我AVCaptureStillImageOutput已经完成了captureStillImageAsynchronouslyFromConnection:completionHandler:方法,我创建了一个NSData对象是这样的:

  NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer]; 

一旦我有NSData对象,我想-without-转换为UIImage旋转图像。我发现我可以转换成CGImage这样做。

当我有了imageData后,我开始转换为CGImage的过程,但是我发现CGImageRef最终比对象NSData大了三十倍。

下面是我用从NSData转换为CGImage代码:

CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)(imageData)); 
CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); 

如果我尝试NSLog出图像的大小,涉及到30兆,当NSData是1.5-2兆字节图片!

size_t imageSize = CGImageGetBytesPerRow(imageRef) * CGImageGetHeight(imageRef); 

    NSLog(@"cgimage size = %zu",imageSize); 

我想,也许当你从NSData的去CGImage,图像解压缩,然后也许如果我改回NSData的,它可能会回到正确的文件大小。

imageData = (NSData *) CFBridgingRelease(CGDataProviderCopyData(CGImageGetDataProvider(imageRef))); 

上面NSData具有相同length作为CGImageRef对象。

如果我试图保存图像,图像是一个30mb图像,无法打开。

我完全是使用CGImage的新手,所以我不确定我是否从NSData转换为CGImage并且返回不正确,或者如果我需要调用某种方法来再次解压缩。

由于提前,

+0

你有没有试过玩'CGImageCreateWithJPEGDataProvider()'的参数?如不插入或不同的意图?这些可能会影响压缩。插值例如可以轻松地增加文件大小,因为颜色混合会增加图像中表示的颜色数量。 –

+0

@RyanPoolos将'shouldInterpolate'设置为No似乎对文件大小没有影响。 我想尽可能地保留原始图像,但它看起来像别的东西正在影响我的代码...即使图像是30兆,我仍然不能保存和查看它,这我目前不能? – Will

回答

4

我在做一些图像处理,并在您的问题来到SO。似乎没有人想出答案,所以这是我的理论。

虽然这是理论上可以转换CGImageRefNSData在你所描述的方式,数据本身是无效的,而不是一个真正的JPEGPNG,因为你的话是不可读取的发现。所以我不认为NSData.length是正确的。你有实际通过若干步骤跳转到重新建立一个CGImageRefNSData表示:

// incoming image data 
NSData *image; 

// create the image ref 
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef) image); 
CGImageRef imageRef = CGImageCreateWithJPEGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); 

// image metadata properties (EXIF, GPS, TIFF, etc) 
NSDictionary *properties; 

// create the new output data 
CFMutableDataRef newImageData = CFDataCreateMutable(NULL, 0); 
// my code assumes JPEG type since the input is from the iOS device camera 
CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef) @"image/jpg", kUTTypeImage); 
// create the destination 
CGImageDestinationRef destination = CGImageDestinationCreateWithData(newImageData, type, 1, NULL); 
// add the image to the destination 
CGImageDestinationAddImage(destination, imageRef, (__bridge CFDictionaryRef) properties); 
// finalize the write 
CGImageDestinationFinalize(destination); 

// memory cleanup 
CGDataProviderRelease(imgDataProvider); 
CGImageRelease(imageRef); 
CFRelease(type); 
CFRelease(destination); 

NSData *newImage = (__bridge_transfer NSData *)newImageData; 

有了这些步骤,newImage.length应该是一样image.length。我没有测试过,因为我实际上是在输入和输出之间进行裁剪,但是基于裁剪,大小与我的预期大致相同(输出大约是输入像素的一半,因此输出长度大约只有一半大小的输入长度)。