web-dev-qa-db-fra.com

Enregistrer des photos dans un album personnalisé dans la photothèque iPhones

J'essaie de créer un album personnalisé dans la photothèque d'un iPhone, puis d'enregistrer les photos que j'ai prises avec l'appareil photo ou choisies dans la pellicule de l'appareil photo du téléphone dans cet album personnalisé. Je peux créer l'album avec succès, mais les photos n'y sont pas enregistrées, mais elles sont enregistrées dans l'album des photos des simulateurs ... Je ne sais pas comment dire à UIImageWriteToSavedPhotosAlbum d'enregistrer dans le nouvel album I viens de créer en utilisant addAssetsGroupAlbumWithName...

Voici le code que j'ai jusqu'à présent - j'ai coupé quelques sections pour garder mon exemple de code court ...

- (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");

            }
     ];
  }
}

Alors ... Comme je l'ai dit, il crée le nouvel album mais n'y enregistre pas la photo. Comment lui dire de sauvegarder dans le nouvel album? Peut-être que je sonne pas utiliser UIImageWriteToSavedPhotosAlbum ??

Remarque: j'utilise Xcode 4.3.2, IOS 5.1 et ARC

23
ElasticThoughts

Si vous utilisez iOS6, la réponse de Fernando ne fonctionnera pas, car le sélecteur saveImage n'est plus disponible.

Le processus est assez déroutant, et je n'ai vu aucune réponse claire publiée, alors voici la méthode que j'ai utilisée pour résoudre ce problème dans iOS6.

Vous devrez utiliser une combinaison des éléments suivants:

Créer l'album:

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

Trouver l'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]);
}];

Enregistrer l'image dans la bibliothèque de ressources et la mettre dans l'album:

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

La réponse de Fernando a fonctionné pour moi dans iOS 7.

Pas :

1) Téléchargez le code ALAssetsLibrary + CustomPhotoAlbum à partir d'ici: http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6 et copiez le 2 fichiers pour la catégorie dans votre projet Xcode.

2) Dans votre fichier d'en-tête, ajoutez les lignes suivantes

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

@property (strong, atomic) ALAssetsLibrary* library;

3) Dans votre fichier d'implémentation, ajoutez les lignes suivantes

@synthesize library=_library;

[~ # ~] modifier [~ # ~] : 4) initialiser l'instance de bibliothèque de ressources, de préférence dans la méthode "viewDidLoad", sinon la méthode saveImage ci-dessous ne s'exécutera pas. (( [~ # ~] confirmé [~ # ~] ):

[Je soumets à nouveau la modification suggérée, car une personne n'ayant pas les compétences en matière d'iphone a rejeté la soumission précédente. C'est sans aucun doute une excellente réponse de @santhu & Fernando et m'a beaucoup aidé, cependant, le morceau de code d'initialisation manquait, il m'a donc fallu un peu de temps pour comprendre pourquoi le code ne fonctionnait pas. Par conséquent, j'apprécierais qu'un modérateur possédant des compétences en développement iPhone revoie la modification.]

_library = [[ALAssetsLibrary alloc] init];

5) Ajoutez ceci dans la méthode où vous souhaitez enregistrer

  //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

Pour les utilisateurs de Swift: - J'ai fait fonction pour faire la même chose.

déclarer la fermeture de la définition de classe surdimensionnée (au-dessus de la définition de classe)

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

déclarer la variable de bibliothèque dans la classe

var library:ALAssetsLibrary?;

initialiser la variable dans viewDidLoad

library = ALAssetsLibrary();

méthode pour ajouter une image à un album particulier

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

appelez cette méthode comme: -

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

Je n'ai pas vu de réponses et de codes vraiment clairs à ces questions. Pour moi, je voulais m'assurer que l'album a été trouvé ou créé, avant d'allumer la caméra. Ce code semble être à peu près correct, et je pense qu'il est un peu plus propre et plus facile à voler ^ H ^ H ^ H ^ H ^ Hstart de.

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

La loi de Tom Duff: volez du code chaque fois que vous le pouvez.

2
Bill Cheswick