【问题标题】:Save Photos to Custom Album in iPhones Photo Library将照片保存到 iPhone 照片库中的自定义相册
【发布时间】:2012-06-12 20:09:06
【问题描述】:

我正在尝试在 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

【问题讨论】:

    标签: iphone objective-c uiimage uiimagepickercontroller alassetslibrary


    【解决方案1】:

    如果您使用的是 iOS6,Fernando 的回答将不起作用,因为 saveImage 选择器不再可用。

    这个过程很混乱,我没有看到任何明确的答案,所以这是我在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]);
         }
     }];
    

    【讨论】:

    • 我的代码出现问题,导致“[groupToAddTo addAsset:asset];”上出现 EXC BAD ACCESS - 请问有什么想法吗?干杯..
    • 一个可能的原因是您的库变量不再有效 - 只要您访问使用它生成的对象,您就需要您的库一直存在;即,您不能让库被释放,然后尝试在 groupToAddTo 上运行选择器...我通常将库设为属性,并在 viewDidLoad 中对其进行初始化。
    • Fernando's 已弃用,我通过在分配 'groupToAddTo = group' 后添加 writeImageToSavedPhotosAlbum 块并使用 'group' 变量而不是 'groupToAddTo :) 为您的帮助干杯
    • @ScottAllen 受您的代码启发,我在下面添加了 swift 版本。
    • 尝试此代码时,我的图像保存在图库和自定义相册中,但我只想保存在自定义相册中,如果有任何方法,请指导我
    【解决方案2】:

    Fernando 的回答在 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方法不会执行。 确认):

    [我正在重新提交建议的编辑,因为非 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]);
        }
    }];
    

    【讨论】:

      【解决方案3】:

      对于 swift 用户:- 我创建函数来做同样的事情。

      声明闭包超大类定义(高于类定义)

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

      【讨论】:

      • 请注意 self.addImage(image, metaData: metadata, toAlbum: "SwiftAlbum") 中的 metaData 位。因为如果没有(这种情况经常发生)你会得到一个错误
      • ALAssetsLibrary 将在 iOS 9.0 中被弃用
      【解决方案4】:

      @Scott Allen 的代码很接近,但第一次不会为我保存图像。因此,如果我还没有创建相册,图像将不会保存。我的解决方案是将创建相册的这个 sn-p 移动到应用委托 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");
                              }];
      

      【讨论】:

        【解决方案5】:

        我还没有看到这些问题的真正明确的答案和代码。对我来说,我想确保在打开相机之前找到或创建了专辑。这段代码似乎是对的,我认为它更干净,更容易窃取^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");
                             }];
        

        汤姆·达夫定律:尽可能窃取代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-26
          • 1970-01-01
          • 2011-07-26
          • 1970-01-01
          • 2010-09-15
          • 1970-01-01
          相关资源
          最近更新 更多