iPhone: 我怎样获取使用UIImageWriteToSavedPhotosAlbum()保存的图片文件路径?

51

我正在使用以下代码将合并后的图片保存到iPhone照片库中:

UIImageWriteToSavedPhotosAlbum(viewImage, self, @selector(savedPhotoImage:didFinishSavingWithError:contextInfo:), nil);

使用以下方法获取回调函数:

- (void) savedPhotoImage:(UIImage*)image didFinishSavingWithError:(NSError *)error contextInfo: (void *)contextInfo { NSLog(@"%@", [error localizedDescription]);
NSLog(@"info: %@", contextInfo);}
我想得到的是图像保存的路径,以便将其添加到数组中,该数组将用于在应用程序的其他位置调用已保存项的列表。
当我使用选择器加载图像时,它会显示路径信息。但是,当我保存已创建的图像时,我找不到从哪里获取已保存的图像路径。
我在网上搜索过,但大多数示例都停留在回调,并显示一条消息,说明图像已成功保存。我只想知道它保存在哪里。
我理解有一种方法可能是开始定义我的自己的路径,但由于该方法为我执行此操作,所以我希望它可以告诉我保存到哪里了。
8个回答

86

我终于找到答案了。显然UIImage方法会剥离元数据,因此使用UIImageWriteToSavedPhotosAlbum是不好的。

然而,在ios4中,苹果推出了一个新的框架来处理照片库,名为ALAssetsLibrary。

首先,您需要右键单击Targets,在构建部分中,使用左下角的小+图标将AlAsset Framework添加到您的项目中。

然后在您的类的头文件中添加#import "AssetsLibrary/AssetsLibrary.h";

最后,您可以使用以下代码:

UIImage *viewImage = YOUR UIIMAGE  // --- mine was made from drawing context
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];  
// Request to save the image to camera roll  
[library writeImageToSavedPhotosAlbum:[viewImage CGImage] orientation:(ALAssetOrientation)[viewImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){  
    if (error) {  
        NSLog(@"error");  
    } else {  
            NSLog(@"url %@", assetURL);  
    }  
}];  
[library release];

这会获取你刚保存的文件的路径。


如何加载图片?我可以从相册加载图片吗?有人可以发布加载图像的代码吗? - Avijit Nagare
11
在iOS 9.0及以上版本中,ALAssetsLibrary已被弃用。请改用PHPhotoLibrary和"performChanges"方法将图像保存到设备中。 - Tys
这条评论需要更多的赞,花了几个小时来实现并让一切正常运行,现在必须使用更新的API重新编写它。 - harrya
2
你能给我们举个例子,展示如何使用PHPhotoLibrary和“performChanges”吗? - Besat
我发现这个很有用 https://dev59.com/o10a5IYBdhLWcg3wipTk - driedler
user1495323在下面的回答中解释了如何按照OP的要求获取文件路径。https://dev59.com/vm855IYBdhLWcg3wPBtx#53627022 - J.C.

3

我的代码是

-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    UIImage *image = [info valueForKey:UIImagePickerControllerOriginalImage];

    imageURL = nil;

    ALAssetsLibraryWriteImageCompletionBlock completeBlock = ^(NSURL *assetURL, NSError *error){
        if (!error) {  
            #pragma mark get image url from camera capture.
            imageURL = [NSString stringWithFormat:@"%@",assetURL];

        }  
    };

    if(image){
        ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library writeImageToSavedPhotosAlbum:[image CGImage] 
                                  orientation:(ALAssetOrientation)[image imageOrientation] 
                              completionBlock:completeBlock];
    }
}

在.h文件中导入库,并定义ALAssetsLibraryWriteImageCompletionBlock的类型定义。
#import <UIKit/UIKit.h>
#import <AssetsLibrary/AssetsLibrary.h>

typedef void (^ALAssetsLibraryWriteImageCompletionBlock)(NSURL *assetURL, NSError *error);

如果您不知道如何获取<AssetsLibrary/AssetsLibrary.h>,请添加现有的框架(AssetsLibrary.framework)。

3

OlivariesF的答案缺少了这个问题的关键部分,即检索路径:

以下是执行所有操作的代码片段:

- (void)processImage:(UIImage*)image type:(NSString*)mimeType forCallbackId:(NSString*)callbackId
    {
        __block NSString* localId;

        // Add it to the photo library
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];

            localId = [[assetChangeRequest placeholderForCreatedAsset] localIdentifier];
        } completionHandler:^(BOOL success, NSError *err) {
            if (!success) {
                NSLog(@"Error saving image: %@", [err localizedDescription]);
            } else {
                PHFetchResult* assetResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localId] options:nil];
                PHAsset *asset = [assetResult firstObject];
                [[PHImageManager defaultManager] requestImageDataForAsset:asset
                                                                  options:nil
                                                            resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
                    NSURL *fileUrl = [info objectForKey:@"PHImageFileURLKey"];
                    if (fileUrl) {
                        NSLog(@"Image path: %@", [fileUrl relativePath]);
                    } else {
                        NSLog(@"Error retrieving image filePath, heres whats available: %@", info);
                    }
                }];
            }
        }];
    }

1
关键字PHImageFileURLKey在PHAsset信息中未找到。 - Priyank Joshi

1

Swift 版本将会是

 ALAssetsLibrary().writeImageToSavedPhotosAlbum(editedImage.CGImage, orientation: ALAssetOrientation(rawValue: editedImage.imageOrientation.rawValue)!,
                completionBlock:{ (path:NSURL!, error:NSError!) -> Void in
                    print("\(path)")
            })

在你的文件中加入"import ALAssetsLibrary"。
项目->构建阶段->链接二进制文件->AssetsLibrary.framework。

0

ALAssetsLibrary已经被弃用。

这是你应该做的方法:

#import <Photos/Photos.h>

UIImage *yourImage;

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    [PHAssetChangeRequest creationRequestForAssetFromImage:yourImage];
} completionHandler:^(BOOL success, NSError *error) {
    if (success) {
        NSLog(@"Success");
    } else {
        NSLog(@"write error : %@",error);
    }
}];

0
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {

    RandomIndexnew = arc4random() % 3;
    if(RandomIndexnew == 0)
    {
        nameStr =[NSString stringWithFormat:@"jpg"];
        textFieldNormalFile_type.text =[NSString stringWithFormat:@"jpg"];
    }
    else if(RandomIndexnew = 1)
    {
        nameStr =[NSString stringWithFormat:@"gif"];
        textFieldNormalFile_type.text =[NSString stringWithFormat:@"GIF"];
    }
    else if(RandomIndexnew = 2)
    {
        nameStr =[NSString stringWithFormat:@"jpg"];
        textFieldNormalFile_type.text =[NSString stringWithFormat:@"JPG"];
    }

    RandomIndex = arc4random() % 20;
    NSString *nameStr1 =[NSString stringWithFormat:@"Image%i",RandomIndex];
    textFieldNormalFile_name.text =[NSString stringWithFormat:@"%@.%@",nameStr1,nameStr];

    newFilePath = [NSHomeDirectory() stringByAppendingPathComponent: textFieldNormalFile_name.text];
    imageData = UIImageJPEGRepresentation(img, 1.0);
    if (imageData != nil) {
        NSLog(@"HERE [%@]", newFilePath);
        [imageData writeToFile:newFilePath atomically:YES];
    }
    image.image =[UIImage imageNamed:newFilePath];
    NSLog(@"newFilePath:%@",newFilePath);
    path.text =[NSString stringWithFormat:newFilePath];
    NSLog(@"path.text :%@",path.text);
}

我正在自己的应用程序中实现这段代码,它可以正常工作。你可以根据自己的需求修改代码以实现相应功能。希望这能对你有所帮助。 - sandy

0

OlivaresF的回答的Swift 4.1版本

        PHPhotoLibrary.shared().performChanges({
                PHAssetChangeRequest.creationRequestForAsset(from: image)
            }) { (success, error) in
                if success {

                } else {
                }
            }

我没有看到你在代码中确切地打印/返回了文件路径,正如OP所要求的那样? - Omar N Shamali

0

Swift 版本

            var localId = ""
            PHPhotoLibrary.shared().performChanges({
                let assetChangeRequest:PHAssetChangeRequest = PHAssetChangeRequest.creationRequestForAsset(from: chosenImage)
                localId = assetChangeRequest.placeholderForCreatedAsset!.localIdentifier
            }) { (success, error) in
                let assetResult:PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [localId], options: nil)
                let asset:PHAsset = assetResult.firstObject!
                PHImageManager.default().requestImageData(for: asset, options: nil) { (imageData, dataUTI, orientation, info) in
                    if let url:URL = info?["PHImageFileURLKey"] as? URL
                    {
                        print("\(url)")
                        
                    }
                    
                }
                
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接