web-dev-qa-db-ja.com

iPhoneのフォトライブラリのカスタムアルバムに写真を保存する

IPhoneのフォトライブラリでカスタムアルバムを作成し、カメラで撮影した写真、または電話のカメラロールから選択した写真をカスタムアルバムに保存しようとしています。アルバムは正常に作成できますが、写真はそこに保存されず、代わりにシミュレータのSaved Photosアルバムに保存されます...新しいアルバムに保存するようにUIImageWriteToSavedPhotosAlbumに指示する方法がわかりません'addAssetsGroupAlbumWithName...を使用して作成しました.

ここに私がこれまでに持っているコードがあります-私は私のコード例を短くするためにいくつかのセクションを切り取りました...

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{     
  NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
  if([mediaType isEqualToString:(__bridge NSString *)kUTTypeImage])
  {        
    // pull GPS information from photos metadata using ALAssetsLibrary
    void (^ALAssetsLibraryAssetForURLResultBlock)(ALAsset *) = ^(ALAsset *asset)
    {
        // code snipped out 
    };
    NSURL *assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
    [library assetForURL:assetURL
             resultBlock:ALAssetsLibraryAssetForURLResultBlock
            failureBlock:^(NSError *error) 
            {
                // code snipped out
            }];

    // getimage from imagePicker and resize it to the max size of the iPhone screen 
    UIImage *originalImage = [info objectForKey:UIImagePickerControllerOriginalImage]; 
    UIImage *resizedImage = [util_ createThumbnailForImage:originalImage thumbnailSize:[util_ determineIPhoneScreenSize]];
    NSData *imageData = UIImagePNGRepresentation(resizedImage);

                // code snipped out
                // code snipped out
                // code snipped out
                // code snipped out
                // code snipped out
                // code snipped out



    // create a new album called "My Apps Photos"
    [library addAssetsGroupAlbumWithName:@"My Apps Photos"
            resultBlock:^(ALAssetsGroup *group) 
            {
                NSLog(@"in addAssetsGroupAlbumWithName resultBlock");

                // save file to album
                UIImageWriteToSavedPhotosAlbum(resizedImage, self, nil, nil);

            } 
            failureBlock:^(NSError *error) 
            {
                NSLog(@"in addAssetsGroupAlbumWithName failureBlock");

            }
     ];
  }
}

だから...私が言ったように、それは新しいアルバムを作成しますが、そこに写真を保存しません。新しいアルバムに保存するように指示するにはどうすればよいですか?おそらくUIImageWriteToSavedPhotosAlbum ??を使用しないように聞こえますか?

注:Xcode 4.3.2、IOS 5.1、およびARCを使用しています

23
ElasticThoughts

IOS6を使用している場合、saveImageセレクターが使用できなくなったため、Fernandoの答えは機能しません。

プロセスはかなり混乱し、明確な答えが投稿されていないので、iOS6でこれを解決するために使用した方法を次に示します。

次の組み合わせを使用する必要があります。

アルバムの作成:

[self.library addAssetsGroupAlbumWithName:albumName 
                              resultBlock:^(ALAssetsGroup *group) {
         NSLog(@"added album:%@", albumName);
}
                             failureBlock:^(NSError *error) {
         NSLog(@"error adding album");
}];

アルバムの検索:

__block ALAssetsGroup* groupToAddTo;
[self.library enumerateGroupsWithTypes:ALAssetsGroupAlbum
                             usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
      if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:albumName]) {
          NSLog(@"found album %@", albumName);
          groupToAddTo = group;
      }
}
                           failureBlock:^(NSError* error) {
     NSLog(@"failed to enumerate albums:\nError: %@", [error localizedDescription]);
}];

画像をアセットライブラリに保存し、アルバムに保存します:

CGImageRef img = [image CGImage];
[self.library writeImageToSavedPhotosAlbum:img
                                  metadata:[info objectForKey:UIImagePickerControllerMediaMetadata]
                           completionBlock:^(NSURL* assetURL, NSError* error) {
     if (error.code == 0) {
         NSLog(@"saved image completed:\nurl: %@", assetURL);

         // try to get the asset
         [self.library assetForURL:assetURL
                       resultBlock:^(ALAsset *asset) {
              // assign the photo to the album
              [groupToAddTo addAsset:asset];
              NSLog(@"Added %@ to %@", [[asset defaultRepresentation] filename], albumName);
          }
                      failureBlock:^(NSError* error) {
              NSLog(@"failed to retrieve image asset:\nError: %@ ", [error localizedDescription]);
          }];
     }
     else {
         NSLog(@"saved image failed.\nerror code %i\n%@", error.code, [error localizedDescription]);
     }
 }];
59
Scott Allen

フェルナンドの答えは、iOS 7でうまくいきました。

手順:

1)ALAssetsLibrary + CustomPhotoAlbumコードをここからダウンロードします: http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6 をコピーXcodeプロジェクト内のカテゴリの2つのファイル。

2)ヘッダーファイルに次の行を追加します

#import <AssetsLibrary/AssetsLibrary.h>
#import "ALAssetsLibrary+CustomPhotoAlbum.h"

@property (strong, atomic) ALAssetsLibrary* library;

3)実装ファイルに、次の行を追加します

@synthesize library=_library;

[〜#〜] edit [〜#〜]:4)アセットライブラリインスタンスを初期化します。できれば「viewDidLoad」メソッドで、それ以外の場合は以下のsaveImageメソッドを使用してください。実行されません。 [〜#〜] confirmed [〜#〜]):

[提案された編集を再送信しています。iPhone以外のスキルを持つ人が以前の投稿を拒否したためです。これは間違いなく@santhuとFernandoによる素晴らしい回答であり、私を大いに助けてくれましたが、初期化コードが欠落していたため、コードが機能しない理由を理解するのに少し時間がかかりました。したがって、iPhone開発スキルセットを持つモデレーターが編集をレビューしてくれれば幸いです。]

_library = [[ALAssetsLibrary alloc] init];

5)保存したいメソッドにこれを追加します

  //Add this in the method where you wish to save
  [self.library saveImage:(UIImage *) toAlbum:(NSString *) withCompletionBlock:^(NSError                 *error) {
    if (error!=nil) {
        NSLog(@"Big error: %@", [error description]);
    }
}];
11
Santhu

Swift users:-同じことをする関数を作成しました。

クラス定義より上でクロージャアウトサイズクラス定義を宣言

typealias CompletionHandler = (success:Bool!) -> Void  

クラス内のライブラリ変数の宣言

var library:ALAssetsLibrary?;

viewDidLoadの変数を初期化する

library = ALAssetsLibrary();

特定のアルバムに画像を追加する方法

func addImage(image:UIImage, metaData:NSDictionary, toAlbum albumName:String, handler:CompletionHandler){

    library?.addAssetsGroupAlbumWithName(albumName, resultBlock: {(group:ALAssetsGroup!) -> Void in
        print("\nAlbum Created:=  \(albumName)");
        /*-- Find Group --*/

        var groupToAddTo:ALAssetsGroup?;

        self.library?.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAlbum),
            usingBlock: { (group:ALAssetsGroup?, stop:UnsafeMutablePointer<ObjCBool>) -> Void in

                if(group != nil){

                    if group!.valueForProperty(ALAssetsGroupPropertyName) as String == albumName{
                        groupToAddTo = group;

                        print("\nGroup Found \(group!.valueForProperty(ALAssetsGroupPropertyName))\n");

                        self.library?.writeImageToSavedPhotosAlbum(image.CGImage, metadata:metaData, completionBlock: {(assetURL:NSURL!,error:NSError!) -> Void in

                            if(error == nil){
                                self.library?.assetForURL(assetURL,
                                    resultBlock: { (asset:ALAsset!) -> Void in
                                        var yes:Bool? = groupToAddTo?.addAsset(asset);
                                        if (yes == true){
                                            handler(success: true);
                                        }
                                    },
                                    failureBlock: { (error2:NSError!) -> Void in
                                        print("Failed to add asset");
                                        handler(success: false);
                                });
                            }
                        });
                    }
                } /*Group Is Not nil*/
            },
            failureBlock: { (error:NSError!) -> Void in
                print("Failed to find group");
                handler(success: false);
        });

        }, failureBlock: { (error:NSError!) -> Void in
            print("Failed to create \(error)");
            handler(success: false);
    });
}

このメソッドを:-と呼びます

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]){

    var image:UIImage = info[UIImagePickerControllerOriginalImage] as UIImage;
    var metadata:NSDictionary = info[UIImagePickerControllerMediaMetadata] as NSDictionary;

    self.addImage(image, metaData: metadata, toAlbum: "SwiftAlbum") { (success) -> Void in
        print("Image Added : \(success)");
    }

    picker.dismissViewControllerAnimated(true, completion: nil);
}
9
Warewolf

@Scott Allenのコードは近いものでしたが、初めて画像を保存することはありませんでした。そのため、アルバムをまだ作成していない場合、画像は保存されません。私の解決策は、アルバムを作成するこのスニペットをアプリデリゲートdidFinishLaunchingWithOptionsに移動することでした。

    NSString *albumName=@"album name";
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library addAssetsGroupAlbumWithName:albumName
                         resultBlock:^(ALAssetsGroup *group) {
                             NSLog(@"added album:%@", albumName);
                         }
                        failureBlock:^(NSError *error) {
                            NSLog(@"error adding album");
                        }];
3
user1837401

これらの質問に対する本当に明確な答えとコードを見たことはありません。私にとっては、カメラを起動する前に、アルバムが検出または作成されたことを確認したかったのです。このコードはほぼ正しいようで、^ H ^ H ^ H ^ H ^ Hstartから少し簡単で盗みやすいと思います。

// find or create our photo album.  If either works
// we fire up the camera. Crazy asynchronous code here.

__weak PhotoVC *weakSelf = self;
__block BOOL found = NO;

ALAssetsLibraryGroupsEnumerationResultsBlock
assetGroupEnumerator = ^(ALAssetsGroup *group, BOOL *stop){
    if (group) {
        NSString *thisGroup = [group valueForProperty:ALAssetsGroupPropertyName];
        if ([album isEqualToString:thisGroup]) {
            NSLog(@"album found!");
            [weakSelf startCamera: group];
            *stop = YES;
            found = YES;
        }
    } else { // not found, create the album
        if (found)
            return;
        NSLog(@"album not found, try making album");

        ALAssetsLibraryGroupResultBlock addGroup =
        ^(ALAssetsGroup *group){
            NSLog(@"album created");
            [weakSelf startCamera: group];
        };

        ALAssetsLibraryAccessFailureBlock addGroupFailed =
        ^(NSError *err){
            NSLog(@"add group failed: %@", [err localizedDescription]);
        };

        [library addAssetsGroupAlbumWithName:album resultBlock:addGroup failureBlock:addGroupFailed];
    }
};

[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
                       usingBlock:assetGroupEnumerator
                     failureBlock:^(NSError *error) {
                         NSLog(@"album access denied");
                     }];

トムダフの法則:可能な限りコードを盗みます。

2
Bill Cheswick