Câu trả lời:
Bạn có thể sử dụng chức năng này:
UIImageWriteToSavedPhotosAlbum(UIImage *image,
id completionTarget,
SEL completionSelector,
void *contextInfo);
Bạn chỉ cần completionTarget , completionSelector và contextinfo nếu bạn muốn được thông báo khi UIImage
được thực hiện tiết kiệm, nếu không bạn có thể vượt qua trong nil
.
Xem tài liệu chính thức choUIImageWriteToSavedPhotosAlbum()
.
Không dùng nữa trong iOS 9.0.
Có cách nhanh hơn UIImageWriteToSattedPhotosAlbum để thực hiện bằng cách sử dụng khung công tác iOS 4.0+ AssetsL Library
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];
ALAssetsLibrary
, nó chỉ mất cùng thời gian để tiết kiệm như UIImageWriteToSavedPhotosAlbum
.
Cách đơn giản nhất là:
UIImageWriteToSavedPhotosAlbum(myUIImage, nil, nil, nil);
Đối với Swift
, bạn có thể tham khảo Lưu vào thư viện ảnh iOS bằng cách sử dụng swift
Một điều cần nhớ: Nếu bạn sử dụng một cuộc gọi lại, hãy đảm bảo rằng bộ chọn của bạn tuân theo mẫu sau:
- (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;
Nếu không, bạn sẽ gặp sự cố với một lỗi như sau:
[NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1]
Chỉ cần truyền hình ảnh từ một mảng đến nó như vậy
-(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);
}
}
Xin lỗi vì typo vừa mới làm điều này một cách nhanh chóng nhưng bạn đã nhận được điểm
Khi lưu một mảng ảnh, không sử dụng vòng lặp for, hãy làm như sau
-(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);
}
}
Trong Swift :
// 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.
}
}
Dưới đây chức năng sẽ làm việc. Bạn có thể sao chép từ đây và dán vào đó ...
-(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");
}
}];
}
Swift 4
func writeImage(image: UIImage) {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.finishWriteImage), nil)
}
@objc private func finishWriteImage(_ image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeRawPointer) {
if (error != nil) {
// Something wrong happened.
print("error occurred: \(String(describing: error))")
} else {
// Everything is alright.
print("saved success!")
}
}
câu trả lời cuối cùng của tôi sẽ làm điều đó ..
đối với mỗi hình ảnh bạn muốn lưu, hãy thêm nó vào 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);
}
}
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];
}
Tôi đã tạo một thể loại UIImageView cho điều này, dựa trên một số câu trả lời ở trên.
Tập tin tiêu đề:
@interface UIImageView (SaveImage) <UIActionSheetDelegate>
- (void)addHoldToSave;
@end
Thực hiện
@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
Bây giờ chỉ cần gọi chức năng này trên hình ảnh của bạn:
[self.imageView addHoldToSave];
Tùy chọn bạn có thể thay đổi tham số minimPressDuration.
Trong Swift 2.2
UIImageWriteToSavedPhotosAlbum(image: UIImage, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)
Nếu bạn không muốn nhận thông báo khi hình ảnh được thực hiện tiết kiệm thì bạn có thể vượt qua con số không trong completionTarget , completionSelector và contextinfo tham số.
Thí dụ:
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.
}
}
Điều quan trọng cần lưu ý ở đây là phương pháp của bạn quan sát việc lưu hình ảnh nên có 3 tham số khác, bạn sẽ gặp phải lỗi NSInvocation.
Hy vọng nó giúp.
Bạn có thể sử dụng cái này
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImageWriteToSavedPhotosAlbum(img.image, nil, nil, nil);
});