Bagaimana cara menyimpan gambar ke perpustakaan foto iPhone?

193

Apa yang harus saya lakukan untuk menyimpan gambar yang telah dihasilkan oleh program saya (mungkin dari kamera, mungkin tidak) ke pustaka foto sistem pada iPhone?

jblocksom
sumber
Anda dapat memeriksa kode ini . Hari yang indah!
Celil Bozkurt

Jawaban:

411

Anda dapat menggunakan fungsi ini:

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

Anda hanya perlu completionTarget , completionSelector dan contextInfo jika Anda ingin diberitahu ketika UIImagedilakukan menghemat, jika tidak, anda dapat lulus dalam nil.

Lihat dokumentasi resmi untukUIImageWriteToSavedPhotosAlbum() .

Martin Gordon
sumber
Ambil +1 untuk jawaban yang akurat
Niru Mukund Shah
Hai terima kasih atas solusi hebat Anda. Di sini saya punya satu keraguan bagaimana kita bisa menghindari duplikat saat menyimpan gambar di perpustakaan foto. Terima kasih sebelumnya.
Naresh
Jika Anda ingin menghemat dalam kualitas yang lebih baik, lihat ini: stackoverflow.com/questions/1379274/…
Eonil
4
Anda sekarang perlu menambahkan 'Privasi - Deskripsi Penggunaan Penambahan Foto Perpustakaan' pada iOS 11 untuk menyimpan foto album pengguna.
horsejockey
1
bagaimana cara memberi nama pada gambar yang disimpan?
Priyal
63

Sudah usang di iOS 9.0.

Ada jauh lebih cepat daripada UIImageWriteToSavedPhotosAlbum cara untuk melakukannya menggunakan kerangka 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];
Denis Fileev
sumber
1
Apakah ada cara untuk menyimpan metadata sewenang-wenang bersama foto?
zakdances
2
Saya mencoba menyimpan menggunakan ALAssetsLibrary, dibutuhkan waktu yang sama untuk menghemat UIImageWriteToSavedPhotosAlbum.
Hlung
Dan ini membekukan kamera :( Saya kira itu tidak didukung latar belakang?
Hlung
Yang ini jauh lebih bersih b / c Anda bisa menggunakan blok untuk menangani penyelesaian.
jpswain
5
Saya menggunakan kode ini dan saya termasuk kerangka kerja ini #import <AssetsLibrary / AssetsLibrary.h> bukan AVFoundation. Bukankah seharusnya jawabannya diedit? @Denis
Julian Osorio
30

Cara paling sederhana adalah:

UIImageWriteToSavedPhotosAlbum(myUIImage, nil, nil, nil);

Sebab Swift, Anda bisa merujuk ke Menyimpan ke perpustakaan foto iOS menggunakan swift

Mutawe
sumber
3
Saya sangat suka ikon profil pengguna SO Anda. Gambar Xcode cukup keren.
Supertecnoboff
1
Sangat sederhana, dan sangat mudah!
Septronic
13

Satu hal yang perlu diingat: Jika Anda menggunakan panggilan balik, pastikan pemilih Anda sesuai dengan formulir berikut:

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

Kalau tidak, Anda akan crash dengan kesalahan seperti berikut ini:

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

Jeff C.
sumber
10

Cukup berikan gambar dari array ke sana seperti itu

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

Maaf untuk kesalahan ketik agak hanya melakukan ini dengan cepat tetapi Anda mengerti maksudnya

mrburns05
sumber
Menggunakan ini akan melewatkan beberapa foto, saya sudah mencobanya. Cara yang benar untuk itu adalah dengan menggunakan panggilan balik dari pemilih selesai.
SamChen
1
dapatkah kita menyimpan gambar dengan nama khusus?
Pengguna 1531343
Orang tidak boleh menggunakan loop untuk ini. Ini mengarah pada kondisi balapan dan crash.
saurabh
4

Saat menyimpan berbagai foto, jangan gunakan loop untuk, lakukan hal berikut

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

Dalam 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.
            }
    }
Raja-Penyihir
sumber
ya ... bagus..tapi setelah menyimpan gambar, saya ingin memuat gambar dari galeri ... bagaimana melakukannya
EI Captain v2.0
4

Fungsi di bawah ini akan berfungsi. Anda dapat menyalin dari sini dan menempel di sana ...

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

Cepat 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!")
    }
}
luhuiya
sumber
1

jawaban terakhir saya akan melakukannya ..

untuk setiap gambar yang ingin Anda simpan, tambahkan ke 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);
        }
}
mrburns05
sumber
Saya sudah mencoba solusi Anda, selalu melewatkan beberapa foto. Lihatlah jawaban saya. tautan
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];
}
Halo
sumber
Jawaban ini tidak benar karena tidak menyimpan gambar ke sistem Photo Library, tetapi ke kotak pasir.
Evan
1

Saya membuat kategori UIImageView untuk ini, berdasarkan pada beberapa jawaban di atas.

File Tajuk:

@interface UIImageView (SaveImage) <UIActionSheetDelegate>
- (void)addHoldToSave;
@end

Penerapan

@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

Sekarang cukup panggil fungsi ini di tampilan gambar Anda:

[self.imageView addHoldToSave];

Secara opsional, Anda dapat mengubah parameter minimumPressDuration.

HugglesNL
sumber
1

Dalam Swift 2.2

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

Jika Anda tidak ingin diberitahu ketika gambar selesai disimpan, maka Anda dapat melewati nol pada parameter completionTarget , completionSelector dan contextInfo .

Contoh:

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

Yang penting untuk dicatat di sini adalah bahwa metode Anda yang mengamati penyimpanan gambar harus memiliki 3 parameter ini yang lain Anda akan mengalami kesalahan NSInvocation.

Semoga ini bisa membantu.

jarora
sumber
0

Anda bisa menggunakan ini

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   UIImageWriteToSavedPhotosAlbum(img.image, nil, nil, nil);
});
Pratik Somaiya
sumber