无需重新压缩即可从用户库中保存/获取JPEG

时间:2012-10-31 01:27:30

标签: ios uiimage ios6 uiimagepickercontroller jpeg

我试图找到一种方法来读取和写入JPEG图像到用户图库(相机胶卷),而无需重新压缩iOS。 UIImage似乎是这里的瓶颈。我发现保存到用户库的唯一方法是UIImageWriteToSavedPhotosAlbum()。有办法解决这个问题吗?

现在我的例程看起来像这样

-Ask UIImagePickerController拍照。当它确实完成了PickingPiaMediaWithInfo时,请执行:

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

- 在磁盘上无损处理JPEG。

- 然后保存回来:

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

以下是3次传球后质量下降情况的微小动画:

JPEG quality degradation

每次执行此操作时显然会变得更糟,但我无法自动执行图像拾取部件,以便在50/100/1000周期内对其进行全面测试。

1 个答案:

答案 0 :(得分:11)

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"]包含从UIImage中选择的已解码UIImagePickerController。你应该改为使用

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]);
  //
};

我可能在代码中犯了一些错误,但步骤如上所列。如果某些东西不能正常工作,或者你想让它更有效率,那么有很多例子可以在堆栈溢出或其他网站上从NSData读取ALAsset