Сохранить фотографии в пользовательский альбом в iPhones Photo Library
Я пытаюсь создать пользовательский альбом в Фотобиблиотеке iPhone, а затем сохранить фотографии, которые я сделал с камерой, или выбрать из камеры Camera Roll для этого пользовательского альбома. Я могу успешно создать альбом, но фотографии там не сохраняются, вместо этого они сохраняются в симуляторах альбома "Сохраненные фотографии"... Я не уверен, как сказать 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
Ответы
Ответ 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]);
}
}];
Ответ 2
Ответ Fernando работал у меня в 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 ниже не будет выполнен. (ПОДТВЕРЖДЕНИЕ):
[Я повторно предлагаю редактирование, потому что кто-то с не-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
Для быстрых пользователей: - Я сделал функцию делать то же самое.
объявить определение класса закрытого класса (определение класса)
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);
}
Ответ 4
Код от @Scott Allen был близок, но не сохранил изображение для меня в первый раз. Поэтому, если у меня еще не было альбома, изображение не будет сохранено. Мое решение состояло в том, чтобы переместить этот фрагмент, который создает альбом для делегата приложения 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");
}];
Ответ 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");
}];
Закон Тома Даффа: кражи кода, когда можете.