ChatGPT解决这个技术问题 Extra ChatGPT

How can I save an image to the camera roll?

I am new to Xcode (using 4.3) and am not sure how to save an image to the device's camera roll. All that I have done so far is set up an IBAction for the button to save the image. What library method or function can I use to save an image to the user's camera roll?


s
smileyborg

You use the UIImageWriteToSavedPhotosAlbum() function.

//Let's say the image you want to save is in a UIImage called "imageToBeSaved"
UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil);

Edit:

//ViewController.m
- (IBAction)onClickSavePhoto:(id)sender{

    UIImageWriteToSavedPhotosAlbum(imageToBeSaved, nil, nil, nil);
}

Let's say I have '- (IBAction)onClickSavePhoto:(id)sender;' in my ViewController.h file, using what you have above, what exactly would I need to place in the ViewController.m file? Thanks again so much!
@user1470914 See my edit. Also, where are you getting the image to be saved to the camera roll? Is it already in your app's bundle, or does the user take a picture and then you save it to the camera roll?
Thanks for your patience qegal. I haven't had a chance to revisit this issue until now. Your EDIT us super helpful. The image is in the app's bundle. There are several images in the app and they can be viewed as small thumbnails. When a small thumbnail is selected it goes to a new view and a fullscreen version can be viewed. I have a button in the right corner of the top nav that says "save" and this is the button that I wish to save the image to the device's cameral roll so that it may be applied as a wallpaper. Thanks again for your help and patience (not sure why casperOne closed this).
I also added UIImageView *imageToBeSaved; to my .h file. I thought that I would have to add @synthesize imageToBeSaved in my .m but I get an error that says "missing context for property implementation declaration"
From iOS10 on, using NSPhotoLibraryUsageDescription key in plist is mandatory. Otherwhise the app crashes.
d
digitalHound

Here's an answer for iOS8+ using the Photos framework.

Objective-C:

#import <Photos/Photos.h>

UIImage *snapshot = self.myImageView.image;

[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
    PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:snapshot];
    changeRequest.creationDate          = [NSDate date];
} completionHandler:^(BOOL success, NSError *error) {
    if (success) {
        NSLog(@"successfully saved");
    }
    else {
        NSLog(@"error saving to photos: %@", error);
    }
}];

Swift:

// Swift 4.0
import Photos

let snapshot: UIImage = someImage

PHPhotoLibrary.shared().performChanges({
    PHAssetChangeRequest.creationRequestForAsset(from: snapshot)
}, completionHandler: { success, error in
    if success {
        // Saved successfully!
    }
    else if let error = error {
        // Save photo failed with error
    }
    else {
        // Save photo failed with no error
    }
})

Here's a link to the Apple documentation.

Don't forget to add the appropriate key/value to your info.plist to request permission to access the photo library:

<key>NSCameraUsageDescription</key>
<string>Enable camera access to take photos.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Enable photo library access to select a photo from your library.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Enable photo library access to save images to your photo library directly from the app.</string>

How can get the image url @ricardopereira
@Mansuu Please have a look at stackoverflow.com/a/37248867/3641812
G
Graham Perks

For reference, you can save videos in a similar manner:

UISaveVideoAtPathToSavedPhotosAlbum(videoPath, nil, nil, nil);

You might want to save a video to upload to Instagram, for example:

// Save video to camera roll; we can share to Instagram from there.
-(void)didTapShareToInstagram:(id)sender { 
    UISaveVideoAtPathToSavedPhotosAlbum(self.videoPath, self, @selector(video:didFinishSavingWithError:contextInfo:), (void*)CFBridgingRetain(@{@"caption" : caption}));
}

- (void)               video: (NSString *) videoPath
    didFinishSavingWithError: (NSError *) error
                 contextInfo: (void *) contextInfoPtr {

    NSDictionary *contextInfo = CFBridgingRelease(contextInfoPtr);
    NSString *caption         = contextInfo[@"caption"];

    NSString *escapedString   = [videoPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; // urlencodedString
    NSString *escapedCaption  = [caption stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; // urlencodedString

    NSURL *instagramURL       = [NSURL URLWithString:[NSString stringWithFormat:@"instagram://library?AssetPath=%@&InstagramCaption=%@", escapedString, escapedCaption]];

    [[UIApplication sharedApplication] openURL:instagramURL];
}

C
Community

Save the image in photo library in Swift 4

Then use following code to save image

UIImageWriteToSavedPhotosAlbum(imageView.image!, nil, nil, nil)

u
user3408691

Use asImage() to get unique content to save to the camera roll.

If you use asImage() you can save a variety of fun things to the camera roll with just a few lines of code! This can be very powerful if the object has some transparency already incorporated.

asImage() works with UITextView, WKWebView, UIImageView, UIButton, UISlider, UITableView to name some objects (but they may need to be visible when you get the image (having a non zero alpha)). I even use it to capture tiling, but that's loaded into a UIImageView already in my design. I suspect asImage() may work with many more object types too, but I only tried the ones I mentioned.

If it's a UITextView, and you set the background color to .clear then the text gets saved with a transparent background. If your text contains emoji or Memoji, you can now get those images into the camera roll, or into UIImageViews internal to your app. Having Memoji/Emoji with a transparent background in your camera roll where they can be used in any variety of applications is powerful.

Other objects may have some transparency if you crop a photo image to a circle, or set the corner radius to clip off the corners.

Note in my code, pointerToTextObjectSelected is a UITextView

    
var pointerToTextObjectSelected = UITextView()
// above populated elsewhere
              
let thisObject = pointerToTextObjectSelected.asImage()
                
let imageData = thisObject.pngData()
                
let imageToSave = UIImage(data: imageData!)
                
UIImageWriteToSavedPhotosAlbum(imageToSave!, nil, nil, nil)

// You will need this extension :

extension UIView {

  // Using a function since `var image` might conflict with an existing variable
  // (like on `UIImageView`)
  func asImage() -> UIImage {
    if #available(iOS 10.0, *) {
      let renderer = UIGraphicsImageRenderer(bounds: bounds)
      return renderer.image { rendererContext in
        layer.render(in: rendererContext.cgContext)
      }
    } else {
      UIGraphicsBeginImageContext(self.frame.size)
      self.layer.render(in:UIGraphicsGetCurrentContext()!)
      let image = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()
      return UIImage(cgImage: image!.cgImage!)
    }
  }
}