2013-10-22 105 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。我沒有測試過,因爲我實際上是在輸入和輸出之間進行裁剪,但是基於裁剪,大小與我的預期大致相同(輸出大約是輸入像素的一半,因此輸出長度大約只有一半大小的輸入長度)。