Как сохранить изображение в библиотеке фотографий iPhone?
Что мне нужно сделать, чтобы сохранить изображение, которое моя программа сгенерировала (возможно, с камеры, возможно, нет) в системную библиотеку фотографий на iPhone?
13 ответов:
вы можете использовать эту функцию:
UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);
вам нужно только completionTarget, completionSelector и contextInfo если вы хотите получать уведомления, когда
UIImage
делается сохранение, в противном случае вы можете перейти вnil
.посмотреть официальная документация
UIImageWriteToSavedPhotosAlbum()
.
устарел в iOS 9.0.
там гораздо быстрее, чем UIImageWriteToSavedPhotosAlbum способ сделать это с помощью iOS 4.0 + AssetsLibrary framework
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){ if (error) { // TODO: error handling } else { // TODO: success handling } }]; [library release];
самый простой способ-это:
UIImageWriteToSavedPhotosAlbum(myUIImage, nil, nil, nil);
на
Swift
, вы можете обратиться к сохранение в библиотеке фотографий iOS с помощью swift
одна вещь, чтобы помнить: если вы используете обратный вызов, убедитесь, что ваш селектор соответствует следующей форме:
- (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;
в противном случае произойдет сбой с ошибкой, например:
[NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1]
просто передайте изображения из массива в него так
-(void) saveMePlease { //Loop through the array here for (int i=0:i<[arrayOfPhotos count]:i++){ NSString *file = [arrayOfPhotos objectAtIndex:i]; NSString *path = [get the path of the image like you would in DOCS FOLDER or whatever]; NSString *imagePath = [path stringByAppendingString:file]; UIImage *image = [[[UIImage alloc] initWithContentsOfFile:imagePath]autorelease]; //Now it will do this for each photo in the array UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); } }
извините за опечатку довольно просто сделал это на лету, но вы получите точку
при сохранении массива фотографий не используйте цикл for, выполните следующие действия
-(void)saveToAlbum{ [self performSelectorInBackground:@selector(startSavingToAlbum) withObject:nil]; } -(void)startSavingToAlbum{ currentSavingIndex = 0; UIImage* img = arrayOfPhoto[currentSavingIndex];//get your image UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } - (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo{ //can also handle error message as well currentSavingIndex ++; if (currentSavingIndex >= arrayOfPhoto.count) { return; //notify the user it's done. } else { UIImage* img = arrayOfPhoto[currentSavingIndex]; UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } }
In Свифт:
// Save it to the camera roll / saved photo album // UIImageWriteToSavedPhotosAlbum(self.myUIImageView.image, nil, nil, nil) or UIImageWriteToSavedPhotosAlbum(self.myUIImageView.image, self, "image:didFinishSavingWithError:contextInfo:", nil) func image(image: UIImage!, didFinishSavingWithError error: NSError!, contextInfo: AnyObject!) { if (error != nil) { // Something wrong happened. } else { // Everything is alright. } }
ниже функция будет работать. Вы можете скопировать отсюда и вставить туда...
-(void)savePhotoToAlbum:(UIImage*)imageToSave { CGImageRef imageRef = imageToSave.CGImage; NSDictionary *metadata = [NSDictionary new]; // you can add ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; [library writeImageToSavedPhotosAlbum:imageRef metadata:metadata completionBlock:^(NSURL *assetURL,NSError *error){ if(error) { NSLog(@"Image save eror"); } }]; }
homeDirectoryPath = NSHomeDirectory(); unexpandedPath = [homeDirectoryPath stringByAppendingString:@"/Pictures/"]; folderPath = [NSString pathWithComponents:[NSArray arrayWithObjects:[NSString stringWithString:[unexpandedPath stringByExpandingTildeInPath]], nil]]; unexpandedImagePath = [folderPath stringByAppendingString:@"/image.png"]; imagePath = [NSString pathWithComponents:[NSArray arrayWithObjects:[NSString stringWithString:[unexpandedImagePath stringByExpandingTildeInPath]], nil]]; if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath isDirectory:NULL]) { [[NSFileManager defaultManager] createDirectoryAtPath:folderPath attributes:nil]; }
мой последний ответ сделает это..
для каждого изображения, которое вы хотите сохранить, добавьте его в NSMutableArray
//in the .h file put: NSMutableArray *myPhotoArray; ///then in the .m - (void) viewDidLoad { myPhotoArray = [[NSMutableArray alloc]init]; } //However Your getting images - (void) someOtherMethod { UIImage *someImage = [your prefered method of using this]; [myPhotoArray addObject:someImage]; } -(void) saveMePlease { //Loop through the array here for (int i=0:i<[myPhotoArray count]:i++){ NSString *file = [myPhotoArray objectAtIndex:i]; NSString *path = [get the path of the image like you would in DOCS FOLDER or whatever]; NSString *imagePath = [path stringByAppendingString:file]; UIImage *image = [[[UIImage alloc] initWithContentsOfFile:imagePath]autorelease]; //Now it will do this for each photo in the array UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); } }
Я создал категорию UIImageView для этого, основываясь на некоторых из ответов выше.
Заголовочный Файл:
@interface UIImageView (SaveImage) <UIActionSheetDelegate> - (void)addHoldToSave; @end
реализация
@implementation UIImageView (SaveImage) - (void)addHoldToSave{ UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; longPress.minimumPressDuration = 1.0f; [self addGestureRecognizer:longPress]; } - (void)handleLongPress:(UILongPressGestureRecognizer*)sender { if (sender.state == UIGestureRecognizerStateEnded) { UIActionSheet* _attachmentMenuSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"Save Image", nil]; [_attachmentMenuSheet showInView:[[UIView alloc] initWithFrame:self.frame]]; } else if (sender.state == UIGestureRecognizerStateBegan){ //Do nothing } } -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ if (buttonIndex == 0) { UIImageWriteToSavedPhotosAlbum(self.image, nil,nil, nil); } } @end
Теперь просто вызовите эту функцию на вашем imageview:
[self.imageView addHoldToSave];
дополнительно можно изменить параметр minimumPressDuration.
на Swift 2.2
UIImageWriteToSavedPhotosAlbum(image: UIImage, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)
Если вы не хотите получать уведомления, когда изображение будет сделано сохранение, то вы можете передать ноль в completionTarget,completionSelector и contextInfo параметры.
пример:
UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.imageSaved(_:didFinishSavingWithError:contextInfo:)), nil) func imageSaved(image: UIImage!, didFinishSavingWithError error: NSError?, contextInfo: AnyObject?) { if (error != nil) { // Something wrong happened. } else { // Everything is alright. } }
здесь важно отметить, что ваш метод, который наблюдает за сохранением изображения, должен иметь эти 3 параметра, иначе вы столкнетесь с ошибками NSInvocation.
надеюсь, что это помогает.