UIImageWriteToSavedPhotosAlbum save as PNG with transparency?

前端 未结 5 1808
轻奢々
轻奢々 2020-12-02 14:44

I\'m using UIImageWriteToSavedPhotosAlbum to save a UIImage to the user\'s photo album. The problem is that the image doesn\'t have transparency and is a JPG. I\'ve got the

相关标签:
5条回答
  • 2020-12-02 15:19

    As an alternative to creating a secondary UIImage for UIImageWriteToSavedPhotosAlbum the PNG data can be written directly using the PHPhotoLibrary.

    Here is a UIImage extension named 'saveToPhotos' which does this:

    extension UIImage {
    
        func saveToPhotos(completion: @escaping (_ success:Bool) -> ()) {
    
            if let pngData = self.pngData() {
    
                PHPhotoLibrary.shared().performChanges({ () -> Void in
    
                    let creationRequest = PHAssetCreationRequest.forAsset()
                    let options = PHAssetResourceCreationOptions()
    
                    creationRequest.addResource(with: PHAssetResourceType.photo, data: pngData, options: options)
    
                }, completionHandler: { (success, error) -> Void in
    
                    if success == false {
    
                        if let errorString = error?.localizedDescription  {
                            print("Photo could not be saved: \(errorString))")
                        }
    
                        completion(false)
                    }
                    else {
                        print("Photo saved!")
    
                        completion(true)
                    }
                })
            }
            else {
                completion(false)
            }
    
        }
    }
    

    To use:

        if let image = UIImage(named: "Background.png") {
            image.saveToPhotos { (success) in
                if success {
                    // image saved to photos
                }
                else {
                    // image not saved
                }
            }
        }
    
    0 讨论(0)
  • 2020-12-02 15:21

    As pointed out on this SO question there is a simple way to save pngs in your Photo Albums:

    UIImage* image = ...;                                     // produce your image
    NSData* imageData =  UIImagePNGRepresentation(image);     // get png representation
    UIImage* pngImage = [UIImage imageWithData:imageData];    // rewrap
    UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil);  // save to photo album
    
    0 讨论(0)
  • 2020-12-02 15:22

    In Swift 5:

    func pngFrom(image: UIImage) -> UIImage {
        let imageData = image.pngData()!
        let imagePng = UIImage(data: imageData)!
        return imagePng
    }
    
    0 讨论(0)
  • 2020-12-02 15:31

    This is a problem I have noticed before and reported on the Apple Developer Forums about a year ago. As far as I know it is still an open issue.

    If you have a moment, please take the time to file a feature request at Apple Bug Report. If more people report this issue, it is more likely that Apple will fix this method to output non-lossy, alpha-capable PNG.

    EDIT

    If you can compose your image in memory, I think something like the following would work or at least get you started:

    - (UIImage *) composeImageWithWidth:(NSInteger)_width andHeight:(NSInteger)_height {
        CGSize _size = CGSizeMake(_width, _height);
        UIGraphicsBeginImageContext(_size);
    
        // Draw image with Quartz 2D routines over here...
    
        UIImage *_compositeImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return _compositeImage;
    }
    
    //
    // cf. https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/FilesandNetworking/FilesandNetworking.html#//apple_ref/doc/uid/TP40007072-CH21-SW20
    //
    
    - (BOOL) writeApplicationData:(NSData *)data toFile:(NSString *)fileName {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        if (!documentsDirectory) {
            NSLog(@"Documents directory not found!");
            return NO;
        }
        NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
        return ([data writeToFile:appFile atomically:YES]);
    }
    
    // ...
    
    NSString *_imageName = @"myImageName.png";
    NSData *_imageData = [NSData dataWithData:UIImagePNGRepresentation([self composeImageWithWidth:100 andHeight:100)];
    
    if (![self writeApplicationData:_imageData toFile:_imageName]) {
        NSLog(@"Save failed!");
    }
    
    0 讨论(0)
  • 2020-12-02 15:33

    I created an extension of UIImage with safe unwrapping:

    Extension

    extension UIImage {
        func toPNG() -> UIImage? {
            guard let imageData = self.pngData() else {return nil}
            guard let imagePng = UIImage(data: imageData) else {return nil}
            return imagePng
        }
    }
    

    Usage:

    let image = //your UIImage
    if let pngImage = image.toPNG() {
         UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil)
    }
    
    0 讨论(0)
提交回复
热议问题