4

我已经使用AVFoundation.

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

         NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];

获得NSData对象后,我想旋转图像而不转换为UIImage. 我发现我可以转换为 aCGImage这样做。

获得 imageData 后,我开始转换为 CGImage 的过程,但我发现CGImageRef最终结果比NSData对象大 30 倍。

这是我用来转换为CGImagefrom的代码NSData

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

如果我尝试缩小图像的大小,当图像是 1.5-2 兆NSLog字节时,它会达到 30 兆字节!NSData

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

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

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

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

以上与对象NSData相同。lengthCGImageRef

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

我对使用 CGImage 完全陌生,所以我不确定我是否正在从 NSData 转换为 CGImage 并错误地转换回来,或者我是否需要调用一些方法来再次解压缩。

提前致谢,

将要

4

1 回答 1

8

我正在做一些图像处理,遇到了你关于 SO 的问题。似乎没有其他人想出答案,所以这是我的理论。

虽然理论上可以按照您描述的方式将 a 转换CGImageRefNSData,但数据本身是无效的,而不是真正的JPEGPNG,因为您发现它不可读。所以我不认为这NSData.length是正确的。您实际上必须跳过许多步骤来重新创建 a 的NSData表示CGImageRef

// 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。我没有测试,因为我实际上在输入和输出之间进行裁剪,但是根据裁剪,大小大致是我预期的(输出大约是输入像素的一半,因此输出长度大约是大小的一半输入长度)。

于 2015-08-25T00:39:13.933 回答