วิธีบันทึกรูปภาพไปยังคลังรูปภาพ iPhone


193

ฉันต้องทำอย่างไรเพื่อบันทึกภาพที่โปรแกรมของฉันสร้างขึ้น (อาจมาจากกล้องถ่ายรูปหรืออาจไม่ใช่) ไปยังคลังรูปภาพระบบบน iPhone


คุณสามารถตรวจสอบรหัสนี้ วันที่ดี!
Celil Bozkurt

คำตอบ:


411

คุณสามารถใช้ฟังก์ชั่นนี้:

UIImageWriteToSavedPhotosAlbum(UIImage *image, 
                               id completionTarget, 
                               SEL completionSelector, 
                               void *contextInfo);

คุณต้องการความสมบูรณ์เป้าหมายเป้าหมาย , ความสมบูรณ์ของตัวเลือกและcontextInfoหากคุณต้องการได้รับการแจ้งเตือนเมื่อการUIImageบันทึกเสร็จสิ้นมิฉะนั้นคุณสามารถส่งnilต่อได้

ดูเอกสารอย่างเป็นทางการสำหรับUIImageWriteToSavedPhotosAlbum()


ใช้ +1 เพื่อคำตอบที่ถูกต้อง
Niru Mukund Shah

สวัสดีขอบคุณสำหรับคำตอบที่ดีของคุณ ที่นี่ฉันมีหนึ่งสงสัยว่าเราสามารถหลีกเลี่ยงการทำซ้ำในขณะที่บันทึกภาพในห้องสมุดภาพ ขอบคุณล่วงหน้า.
Naresh

หากคุณต้องการประหยัดด้วยคุณภาพที่ดีขึ้นให้ดูที่: stackoverflow.com/questions/1379274/…
eonil

4
ตอนนี้คุณจะต้องเพิ่ม 'ความเป็นส่วนตัว - คำอธิบายการใช้งานการเพิ่มคลังรูปภาพ' ใน iOS 11 เพื่อบันทึกรูปภาพอัลบั้มผู้ใช้
horsejockey

1
จะตั้งชื่อภาพที่บันทึกได้อย่างไร?
Priyal

63

เลิกใช้แล้วใน iOS 9.0

มีมากขึ้นอย่างรวดเร็วแล้ว UIImageWriteToSavedPhotosAlbum วิธีที่จะทำมันโดยใช้ iOS 4.0+ สินทรัพย์กรอบห้องสมุด

    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];

1
มีวิธีการบันทึกเมตาดาต้าโดยพลการพร้อมกับภาพถ่ายหรือไม่?
zakdances

2
ฉันพยายามประหยัดการใช้ก็จะใช้เวลาเพียงแค่ในเวลาเดียวกันเพื่อบันทึกเป็นALAssetsLibrary UIImageWriteToSavedPhotosAlbum
Hlung

และนี่ก็ทำให้กล้องค้าง :( ฉันเดาว่ามันไม่รองรับพื้นหลังเหรอ?
Hlung

อันนี้สะอาดมาก b / c คุณสามารถใช้บล็อกเพื่อจัดการกับความสมบูรณ์
jpswain

5
ฉันใช้รหัสนี้และฉันรวมกรอบงานนี้ #import <AssetsLibrary / AssetsLibrary.h> ไม่ใช่ AVFoundation คำตอบไม่ควรถูกแก้ไขหรือ @Denis
Julian Osorio

30

วิธีที่ง่ายที่สุดคือ:

UIImageWriteToSavedPhotosAlbum(myUIImage, nil, nil, nil);

สำหรับSwift, คุณสามารถอ้างถึงการบันทึกไปยังคลังภาพ iOS โดยใช้ swift


3
ฉันชอบไอคอนโปรไฟล์ผู้ใช้ SO ของคุณจริงๆ ภาพ Xcode สวย ๆ
Supertecnoboff

1
ง่ายน่าอัศจรรย์และง่ายมาก!
58

13

สิ่งหนึ่งที่ควรจดจำ: หากคุณใช้การโทรกลับตรวจสอบให้แน่ใจว่าตัวเลือกของคุณเป็นไปตามแบบฟอร์มต่อไปนี้:

- (void) image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo;

มิฉะนั้นคุณจะมีปัญหากับข้อผิดพลาดดังต่อไปนี้:

[NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1]


10

เพียงส่งภาพจากอาเรย์มาให้อย่างนั้น

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

ขออภัยที่คนพิมพ์ผิดเพียงแค่ทำสิ่งนี้ในทันที แต่คุณได้รับจุด


การใช้สิ่งนี้จะทำให้ภาพถ่ายบางส่วนหายไปฉันได้ลองแล้ว วิธีที่ถูกต้องคือใช้การโทรกลับจากตัวเลือกความสมบูรณ์
SamChen

1
เราสามารถบันทึกรูปภาพด้วยชื่อที่กำหนดเองได้หรือไม่?
ผู้ใช้ 1531343

หนึ่งไม่ควรใช้สำหรับการวนซ้ำสำหรับเรื่องนี้ มันนำไปสู่สภาพการแข่งขันและล้มเหลว
saurabh

4

เมื่อบันทึกอาเรย์ของภาพถ่ายอย่าใช้สำหรับลูปให้ทำดังต่อไปนี้

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

4

ในสวิฟท์ :

    // 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.
            }
    }

ใช่ ... ดี .. แต่หลังจากบันทึกภาพฉันต้องการโหลดภาพจากแกลเลอรี่ ... วิธีการทำเช่นนั้น
EI Captain v2.0

4

ฟังก์ชั่นด้านล่างจะทำงาน คุณสามารถคัดลอกจากที่นี่และวางที่ ...

-(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");
        }
    }];
}

2

สวิฟท์ 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!")
    }
}

1

คำตอบสุดท้ายของฉันจะทำ ..

สำหรับแต่ละอิมเมจที่คุณต้องการบันทึกให้เพิ่มลงใน 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);
        }
}

ฉันได้ลองวิธีแก้ปัญหาของคุณแล้วมันมักจะพลาดภาพถ่าย ดูคำตอบของฉัน ลิงก์
SamChen

1
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];
}

คำตอบนี้ไม่ถูกต้องเพราะมันไม่ได้บันทึกภาพไปยังคลังภาพระบบ แต่ไปที่กล่องทราย
Evan

1

ฉันสร้างหมวดหมู่ 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

ตอนนี้เพียงเรียกใช้ฟังก์ชันนี้ในมุมมองภาพของคุณ:

[self.imageView addHoldToSave];

คุณสามารถเลือกที่จะเปลี่ยนแปลงพารามิเตอร์


1

ในSwift 2.2

UIImageWriteToSavedPhotosAlbum(image: UIImage, _ completionTarget: AnyObject?, _ completionSelector: Selector, _ contextInfo: UnsafeMutablePointer<Void>)

หากคุณไม่ต้องการรับการแจ้งเตือนเมื่ออิมเมจเสร็จสิ้นการบันทึกคุณอาจส่งผ่านศูนย์ในพารามิเตอร์เสร็จสมบูรณ์เป้าหมาย , 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

หวังว่ามันจะช่วย


0

คุณสามารถใช้สิ่งนี้

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   UIImageWriteToSavedPhotosAlbum(img.image, nil, nil, nil);
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.