2012-10-31 20 views
6

我試圖找到一種方法來讀取和寫入JPEG圖像到用戶庫(相機膠捲),而無需iOS重新壓縮它們。 UIImage似乎是這裏的瓶頸。保存到用戶庫的唯一方法是我找到的是UIImageWriteToSavedPhotosAlbum()。有沒有解決的辦法?保存爲/從用戶庫中獲取JPEG而無需重新壓縮

現在我的日常看起來像這樣

-Ask的UIImagePickerController相片。而當它didFinishPickingMediaWithInfo,這樣做:

NSData *imgdata = [NSData dataWithData:UIImageJPEGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"], 1)]; 
[imgdata writeToFile:filePath atomically:NO]; 

-Process JPEG無損磁盤上。

- 然後將其重新保存:

UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:[self getImagePath]], self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 

這是什麼質量的降低看起來像3次後,一個小動畫:

JPEG quality degradation

它每次我這樣做的時候明顯惡化,但我無法自動完成圖像採集部分,以便對其進行50/100/1000週期的全面測試。

回答

10

UIImage解碼的圖像數據,因此它可以被編輯和顯示,所以

UIImageWriteToSavedPhotosAlbum([UIImage imageWithContentsOfFile:[NSData dataWithContentsOfFile:[self getImagePath]]], self, @selector(image:didFinishSavingWithError:contextInfo:), nil); 

將第一解碼圖像,並且比編碼回由UIImageWriteToSavedPhotosAlbum方法。

相反,你應該使用ALAssetsLibrary/writeImageDataToSavedPhotosAlbum:metadata:completionBlock:,像這樣:

ALAssetsLibrary *assetLib = [[[ALAssetsLibrary alloc] init] autorelease]; 
[assetLib writeImageDataToSavedPhotosAlbum:[self getImagePath] metadata:nil completionBlock:nil]; 

您還可以通過元數據和完成塊的呼叫。

編輯:

用於獲取圖像:

[info objectForKey:@"UIImagePickerControllerOriginalImage"]含有UIImagePickerController選擇的解碼UIImage。您應該改用

NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL]; 

使用assetURL可以使用ALAssetsLibrary/assetForURL:resultBlock:failureBlock:方法現在得到ALAsset它:

ALAssetsLibrary *assetLib = [[[ALAssetsLibrary alloc] init] autorelease]; 
[assetLib assetForURL:assetURL resultBlock:resultBlock failureBlock:failureBlock]; 

現在你可以得到圖像的不變的NSData:

ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *asset){ 
    ALAssetRepresentation *assetRep = [asset defaultRepresentation]; 
    long long imageDataSize = [assetRepresentation size]; 
    uint8_t* imageDataBytes = malloc(imageDataSize); 
    [assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil]; 
    NSData *imageData = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES]; // you could for instance read data in smaller buffers and append them to your file instead of reading it all at once 
    // save it 
    [imgdata writeToFile:filePath atomically:NO]; 
}; 
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror){ 
    NSLog(@"Cannot get image - %@",[myerror localizedDescription]); 
    // 
}; 

我可能在代碼中犯了一些錯誤,但步驟如上所列。如果某些功能不能正常工作,或者希望使其效率更高一些,則可以使用很多示例來執行諸如在計算器或其他站點上從ALAsset讀取NSData

+0

是的,謝謝,我已經通過AssetsLibrary發現了這個技巧。我希望你的回答對別人有幫助。 – Kai