什么是从iPhone相册导入和保存照片的正确方法?

我正在从iPhone相册导入照片到我的应用程序的文档文件夹。 这是我的代码。

for (int j=0; j<[assetArray count]; j++) { ALAsset *assest = [assetArray objectAtIndex:j]; CGImageRef imageRef = assest.defaultRepresentation.fullResolutionImage; UIImage *image = [UIImage imageWithCGImage:imageRef]; NSData *imageData = UIImageJPEGRepresentation(image); [imageData writeToFile:documentsPath atomically:YES]; } 

它的工作正常,但是当我尝试导入更高分辨率的图像需要更多的时间。 用最less的时间导入正确的方法是什么? 顺便说一句:我把image转换成NSData需要更多的时间。

出于多种原因,使用fullResolutionImage完成此任务是很危险的。 一些评论:

  1. 对于大图像可能会发生内存问题。 当使用fullResolutionImage方法。 请注意,照片库(至less在iPad上)也可以包含RAW图像。
  2. 从图像文件内部,性能是次优的ImageIO首先创build一个CGImageRef,然后将其转换为JPEG。 这需要时间。
  3. AssetLibrary也可以包含video。 在这种情况下,FullResolutionImage只返回video的previewImage,而不是实际的video。
  4. 存储实际的资产对象是没问题的,因为它们在内存中很小。

将图像写入文档目录的更好方法是使用ALAssetsRepresentation的getBytes方法。 这应该是更快,更有效的记忆方式。 它也给你原始的图像文件(包括元数据),也适用于video。

您的示例代码重写然后将如下所示:

 //reading out the orginal images for (int j=0; j<[assetArray count]; j++) { ALAssetRepresentation *representation = [[assetArray objectAtIndex:j] defaultRepresentation]; NSString* filename = [documentPath stringByAppendingPathComponent:[representation filename]]; [[NSFileManager defaultManager] createFileAtPath:filename contents:nil attributes:nil]; NSOutputStream *outPutStream = [NSOutputStream outputStreamToFileAtPath:filename append:YES]; [outPutStream open]; long long offset = 0; long long bytesRead = 0; NSError *error; uint8_t * buffer = malloc(131072); while (offset<[representation size] && [outPutStream hasSpaceAvailable]) { bytesRead = [representation getBytes:buffer fromOffset:offset length:131072 error:&error]; [outPutStream write:buffer maxLength:bytesRead]; offset = offset+bytesRead; } [outPutStream close]; free(buffer); } //reading out the fullScreenImages and thumbnails for (int j=0; j<[assetArray count]; j++) { @autoreleasepool { ALAsset *asset = [assetArray objectAtIndex:j]; NSString *orgFilename = [representation filename]; NSString *filenameFullScreen = [NSString stringWithFormat:@"%@_fullscreen.png",[orgFilename stringByDeletingPathExtension]] NSString* pathFullScreen = [documentPath stringByAppendingPathComponent:filenameFullScreen]; CGImageRef imageRefFullScreen = [[asset defaultRepresentation] fullScreenImage]; UIImage *imageFullScreen = [UIImage imageWithCGImage:imageRefFullScreen]; NSData *imageDataFullScreen = UIImagePNGRepresentation(imageFullScreen); [imageDataFullScreen writeToFile:pathFullScreen atomically:YES]; NSString *filenameThumb = [NSString stringWithFormat:@"%@_thumb.png",[orgFilename stringByDeletingPathExtension]] NSString* pathThumb = [documentPath stringByAppendingPathComponent:filenameThumb]; CGImageRef imageRefThumb = [asset thumbnail]; UIImage *imageThumb = [UIImage imageWithCGImage:imageRefThumb]; NSData *imageDataThumb = UIImagePNGRepresentation(imageThumb); [imageDataThumb writeToFile:pathThumb atomically:YES]; } } 

我正在使用ELCImagePicker,并在使用声明从照片库一次导入多张照片时面临同样的问题。 我们不能减less导入时间,但崩溃问题将得到解决。

 for (int j=0; j<[assetArray count]; j++) { @autoreleasepool // This is compiler level feature so will only work on xcode 4.1 or above { ALAsset *assest = [assetArray objectAtIndex:j]; CGImageRef imageRef = assest.defaultRepresentation.fullResolutionImage; UIImage *image = [UIImage imageWithCGImage:imageRef]; NSData *imageData = UIImagePNGRepresentation(image); [imageData writeToFile:documentsPath atomically:YES]; } } 

如果可能的话,尝试只将assetURL存储在assetArray中,而不是整个ALAsset对象,并从url中一次创buildALAsset,这可能有助于减less内存消耗。 在这种情况下,您将需要使用块

 ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset) { CGImageRef iref = [[myasset defaultRepresentation] fullResolutionImage]; if (iref) //You have image so use it { } }; ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror) { NSLog(@"Can't get image - %@",[myerror localizedDescription]); }; ALAssetsLibrary* assetslibrary = [[[ALAssetsLibrary alloc] init] autorelease]; [assetslibrary assetForURL:imageURL resultBlock:resultblock failureBlock:failureblock];