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

标签 ios uiimage ios6 uiimagepickercontroller jpeg

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

现在我的例程是这样的

——向 UIImagePickerController 请求一张照片。当它执行 FinishPickingMediaWithInfo 时,执行:

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 次循环的全面测试。

最佳答案

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];

您还可以将元数据和完成 block 传递给调用。

编辑:

获取图片:

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

我可能在代码中犯了一些错误,但步骤如上所列。如果出现问题,或者如果你想让它更有效一点,有很多例子可以做一些事情,比如从 stackoverflow 上的 ALAsset 读取 NSData或其他网站。

关于ios - 无需重新压缩即可从用户图库保存/获取 JPEG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13150017/

相关文章:

ios - 在 UICollectionViewCell 中隐藏 UIImage

ios - 如何垂直平铺 UIImage 而仅在 iOS 上水平拉伸(stretch)?

iphone - 更改 UITabBarController 的 View Controller

swift - WatchKit 检索多个 URL 图像

ios - 我的UIImage在屏幕上哪里?

ios - 来自 UITableView 部分的条件目标 View Controller

iphone - 自定义书签图标添加到 UISearchBar

ios - "GoogleMobileAds/GoogleMobileAds.h"找不到文件错误

ios - 不兼容的整数到指针的转换将 'NSInteger'(又名 'int')发送到类型为 'NSInteger *'(又名 'int *')的参数

ios - 在 iOS 中访问街道数据