7

我正在尝试找到一种方法来读取和写入 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 质量下降

显然每次我这样做都会变得更糟,但我无法自动化图像拾取部分以对其进行 50/100/1000 个周期的全面测试。

4

1 回答 1

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您现在可以ALAsset使用ALAssetsLibrary/assetForURL:resultBlock:failureBlock:方法获取它:

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

我可能在代码中犯了一些错误,但步骤如上所列。如果某些事情不能正常工作,或者如果你想让它更有效率,有很多例子可以做一些事情,比如NSDataALAssetstackoverflow 或其他网站上阅读。

于 2013-01-31T07:57:42.663 回答