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