22

我正嘗試在iPhone的照片庫中創建自定義相冊,然後保存我用相機拍攝的照片或從手機相機膠捲中選擇的相片自定義相冊。我可以成功創建相冊,但照片不會保存在那裏,而是保存到模擬器保存的照片專輯...我不知道如何告訴UIImageWriteToSavedPhotosAlbum保存到我剛剛創建的新專輯addAssetsGroupAlbumWithName ...將照片保存到iPhone相冊中的自定義相冊

這裏是我的代碼到目前爲止 - 我剪斷了幾個部分,以保持我的代碼示例短...

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

回答

59

如果使用的是iOS6的,阿隆索的回答是行不通的,因爲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]); 
    } 
}]; 
+0

我得到一個問題與我們的代碼造成的「[一個EXC錯誤訪問groupToAddTo addAsset:asset];' - 有什麼想法嗎?乾杯.. – theiOSDude

+0

一個可能的原因是您的庫變量不再有效 - 只要您訪問使用它生成的對象,您就需要您的庫保持一段時間;即你不能讓庫去分配,然後嘗試在groupToAddTo上運行一個選擇器...我通常使庫成爲一個屬性,並在viewDidLoad中初始化它。 –

+0

Fernando的答案在iOS 6.0.1中爲我工作 –

3

從@Scott艾倫的代碼很接近,但不會將圖像保存爲我的第一次。所以如果我還沒有創建相冊,圖像將無法保存。我的解決辦法,以推動這一片段,創建相冊應用程序的委託didFinishLaunchingWithOptions:

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

我還沒有看到真正明確的答案和代碼到這些問題。對於我來說,我想確保在我啓動相機之前找到或創建相冊。這段代碼似乎是正確的,我認爲這是一個更清潔,更容易竊取^ 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"); 
        }]; 

湯姆達夫法則:只要你可以竊取代碼。

11

阿隆索的回答中的iOS 7工作對我來說

步驟:

1)從這裏下載ALAssetsLibrary + CustomPhotoAlbum代碼:http://www.touch-code-magazine.com/wp-content/uploads/2011/11/ALAssetsLibrary_CustomPhotoAlbum.zip?a071b6並複製2個文件到您的Xcode項目中的類別。

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

爲我工作,謝謝。 – makkuzu

+0

在iOS8上不起作用。 – SarpErdag

9

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

在iOS8(8.1.3)中使用魅力感謝 – TimWhiting

+0

請注意self.addImage中的metaData位(image,metaData:metadata,toAlbum:「SwiftAlbum」)。因爲如果沒有(通常是這種情況),你會得到一個錯誤 – TimWhiting

+3

ALAssetsLibrary將在iOS 9.0中棄用 – Lucas

相關問題