22

Próbuję utworzyć niestandardowy album w bibliotece zdjęć iPhone'a, a następnie zapisać zdjęcia zrobione aparatem lub wybrać z aparatu Camera Roll do tego albumu niestandardowy album. Mogę z powodzeniem utworzyć album, ale zdjęcia nie są tam zapisywane, zamiast tego są zapisywane na symulatorze. Album Saved Photos ... Nie wiem, jak powiedzieć UIImageWriteToSavedPhotosAlbum, aby zapisać do nowego albumu, który właśnie utworzyłem przy użyciu addAssetsGroupAlbumWithName ...Zapisywanie zdjęć w niestandardowym albumie w iPhones Photo Library

Oto kod mam tak daleko - mam wycięte z kilku odcinków, aby moje przykład kodu krótki ...

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

      } 
    ]; 
    } 
} 

więc ... Jak mówiłem, to tworzy nowy album, ale nie zapisuje tam zdjęcia. Jak mam powiedzieć, aby zapisać na nowym albumie? Być może brzmi nie używać UIImageWriteToSavedPhotosAlbum?

Uwaga: Używam Xcode 4.3.2, iOS 5.1 i Łuk

Odpowiedz

59

Jeśli używasz iOS6, Fernando odpowiedź nie będzie działać, ponieważ selektor saveImage nie jest już dostępny.

Proces ten jest dość zagmatwany i nie widziałem żadnych wyraźnych odpowiedzi opublikowanych, więc oto metoda, którą użyłem, aby rozwiązać ten problem w iOS6.

Trzeba będzie użyć kombinacji następujących:

Utwórz Album:

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

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

zapisać obraz Biblioteka zasobów i umieść ją w albumie:

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

pojawia się problem z naszym kodzie powodując BAD DOSTĘPU EXC na „[ groupToAddTo addAsset: asset]; ' - Czy masz jakieś pomysły? Pozdrawiam .. – theiOSDude

+0

Jedną z możliwych przyczyn jest to, że twoja zmienna biblioteczna nie jest już ważna - musisz mieć swoją bibliotekę tak długo, jak masz dostęp do obiektów, które przez nią wygenerowałeś; tzn. nie można pozwolić, aby biblioteka otrzymała dealloc'd, a następnie spróbuj uruchomić selektor w groupToAddTo ... Zazwyczaj sprawiam, że biblioteka jest właściwością i zainicjuję ją w viewDidLoad. –

+0

Odpowiedź od Fernando pracowała dla mnie w iOS 6.0.1 –

3

Kod z @Scott Allen był blisko, ale nie zapisałbym go po raz pierwszy. Więc jeśli nie mam jeszcze utworzonego albumu, obraz nie zostanie zapisany. Moje rozwiązanie było przenieść ten fragment, który tworzy płytę do didFinishLaunchingWithOptions aplikacja Delegat:

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

nie widziałem naprawdę jasnych odpowiedzi i kodu na te pytania. Dla mnie chciałem się upewnić, że album został znaleziony lub stworzony, zanim uruchomię aparat. Ten kod wydaje się być w porządku, i myślę, że jest trochę czystszy i łatwiej ukraść^H^H^H^H^Hstart from.

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

Prawo Toma Duffa: kradnij kod, kiedy tylko możesz.

11

odpowiedź Fernando pracował dla mnie w iOS 7.

Kroki:

1) Pobierz kod ALAssetsLibrary + CustomPhotoAlbum stąd: http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6 i skopiuj 2 pliki do kategorii wewnątrz projektu Xcode.

2) W pliku nagłówkowym, należy dodać następujące linie

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

@property (strong, atomic) ALAssetsLibrary* library; 

3) w pliku implementacji, należy dodać następujące linie

@synthesize library=_library; 

EDIT: 4) inicjalizacji biblioteki zasobów przykład, najlepiej w metodzie "viewDidLoad", w przeciwnym razie metoda saveImage nie zostanie wykonana. (POTWIERDZONE):

[ja ponownym sugerowanego zmienił, bo ktoś z umiejętnościami non-iphone odrzucił poprzedniego zgłoszenia. Jest to bez wątpienia wspaniała odpowiedź @santhu & Fernando i bardzo mi pomogła, jednak brakowało kodu inicjalizacyjnego, więc zajęło mi trochę czasu, aby dowiedzieć się, dlaczego kod nie działa. Stąd też byłbym wdzięczny jeśli moderator z iPhone skillset rozwoju opinie edit]

_library = [[ALAssetsLibrary alloc] init]; 

5) Dodaj to w sposobie, w którym chcesz zapisać

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

Pracowałem dla mnie, dzięki. – makkuzu

+0

Nie działa na iOS8. – SarpErdag

9

do szybkiego użytkowników: -. Zrobiłem funkcja, aby zrobić to samo.

zamknięcie stwierdzenie definicja wielkogabarytowych klasy (powyżej definicji klasy)

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

zadeklarować zmienną biblioteki wewnątrz klasy

var library:ALAssetsLibrary?; 

inicjalizacji zmiennych w viewDidLoad

library = ALAssetsLibrary(); 

metoda dodać zdjęcie do określonego albumu

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

wywołanie tej metody, jak: -

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

Działa jako charm w iOS8 (8.1.3) dzięki – TimWhiting

+0

Należy uważać z bitem metaData w self.addImage (image, metaData: metadane, toAlbum: "SwiftAlbum"). Ponieważ jeśli nie ma żadnych (co często się zdarza), dostaniesz błąd – TimWhiting

+3

ALAssetsLibrary będzie przestarzałe w iOS 9.0 – Lucas

Powiązane problemy