【问题标题】:UIImageWriteToSavedPhotosAlbum save as PNG with transparency?UIImageWriteToSavedPhotosAlbum 保存为透明的PNG?
【发布时间】:2023-03-08 00:28:01
【问题描述】:

我正在使用 UIImageWriteToSavedPhotosAlbum 将 UIImage 保存到用户的相册。问题是图像没有透明度并且是JPG。我已将像素数据正确设置为 具有 透明度,但似乎没有办法以支持透明度的格式保存。想法?

编辑:没有办法做到这一点,但是还有其他方法可以将 PNG 图像传递给用户。其中之一是将图像保存在 Documents 目录中(如下所述)。完成后,您可以通过电子邮件发送它,将其保存在数据库中,等等。除非它是有损不透明 JPG,否则您无法将其放入相册(目前)。

【问题讨论】:

    标签: iphone uiimage quartz-graphics


    【解决方案1】:

    我创建了一个 UIImage 扩展,可以安全展开:

    扩展

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

    用法

    let image = //your UIImage
    if let pngImage = image.toPNG() {
         UIImageWriteToSavedPhotosAlbum(pngImage, nil, nil, nil)
    }
    

    【讨论】:

      【解决方案2】:

      作为为 UIImageWriteToSavedPhotosAlbum 创建辅助 UIImage 的替代方法,可以使用 PHPhotoLibrary 直接写入 PNG 数据。

      这是一个名为“saveToPhotos”的 UIImage 扩展,它执行此操作:

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

      使用方法:

          if let image = UIImage(named: "Background.png") {
              image.saveToPhotos { (success) in
                  if success {
                      // image saved to photos
                  }
                  else {
                      // image not saved
                  }
              }
          }
      

      【讨论】:

        【解决方案3】:

        在 Swift 5 中:

        func pngFrom(image: UIImage) -> UIImage {
            let imageData = image.pngData()!
            let imagePng = UIImage(data: imageData)!
            return imagePng
        }
        

        【讨论】:

          【解决方案4】:

          正如this SO question 中指出的那样,一种在相册中保存 png 的简单方法:

          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
          

          【讨论】:

          • 谢谢。像魅力一样工作。
          • 完美。感谢发帖。
          【解决方案5】:

          这是我之前注意到的一个问题,并在大约一年前在Apple Developer Forums 上报告过。据我所知,这仍然是一个悬而未决的问题。

          如果您有时间,请花时间在Apple Bug Report 提交功能请求。如果更多人报告此问题,Apple 很有可能会修复此方法以输出无损、支持 alpha 的 PNG。

          编辑

          如果您可以在内存中构图,我认为以下方法会起作用,或者至少可以帮助您入门:

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

          【讨论】:

          • 完成了。我听说有一种方法可以将图像以无损格式保存到文档文件夹中。知道该怎么做吗?
          • 我已经更新了我的答案。希望这可以帮助您入门。
          • 漂亮!创造了奇迹。该图像是 PNG 并且具有透明度,我只需要找到它就可以了。
          • 我不明白这是如何工作的。原始图像数据的引用在哪里?通过阅读代码,它看起来像是创建了一个“空白”图像,开发人员指定了高度和宽度。我想从相机中传入一个 UIImage 对象。
          • 请查看下面的stackoverflow.com/a/10279075/129202,它适用于UIImageWriteToSavedPhotosAlbum,无需保存到文档文件夹。
          猜你喜欢
          • 1970-01-01
          • 2011-06-11
          • 2015-06-17
          • 1970-01-01
          • 2015-04-17
          • 2015-06-24
          • 2013-04-11
          • 2019-03-18
          • 2014-10-05
          相关资源
          最近更新 更多