UIImageView没有显示来自UIImagePickerController的PNG图像的透明度

时间:2015-10-04 18:05:27

标签: ios swift uiimageview png uiimagepickercontroller

我当然希望我错过了一些东西,因为我不明白为什么这样做会有所作为。我有一个PNG图像,它具有完全透明的背景,因为我想将它叠加在UIImageView内的其他图像上。

XCode项目中包含的PNG图像都可以正常工作。问题是当我使用UIImagePickerController动态选择这些相同的PNG图像然后将其分配给UIImageView时,出于某些非常奇怪的原因,它不会将其视为具有透明度的PNG图像而是它添加了白色背景。

之前有人见过这个,我该如何解决这个问题?

*更新#1:我决定尝试一些似乎证实我理论的东西。我决定给自己发送电子邮件给我保存到我设备上的原始PNG图像,然后看到这些图像以JPG的形式传给我。在我看来,当你将图像保存到iPhone上的照片时它将它转换为JPG,这对我来说相当震撼。希望有人能解决这个问题。原始图片testImage1.pngtestImage2.png已保存到照片中,然后通过电子邮件发回给自己,并以IMG_XXXX.jpgIMG_XXXX.jpg

返回

*更新#2:我一直在玩这个,我发现了一些事情,并在此过程中能够回答我自己的问题。 (1)我在UPDATE#1中的理论是部分正确的,但保存Photo时转换不会发生,看起来就像是在飞行中。内部照片存储了原始图片扩展名(2)当我在UIImagePickerControllerDelegate中意识到我正在使用时,我能够验证这一点

let imageData = UIImageJPEGRepresentation(image, 1.0)

而不是

let imageData = UIImagePNGRepresentation(image)

当我使用第二行代码时,它识别出图像的原始透明属性。

3 个答案:

答案 0 :(得分:8)

是的,对UIImageJPEGRepresentation的调用会将生成的图像转换为JPEG,但不支持透明度。

顺便说一下,如果您的目的是出于其他原因(例如上传到服务器,发送电子邮件等)获取图片的NSData,我建议针对UIImageJPEGRepresentation和{{1} }。它们会丢失元数据,可以使资产变大,如果使用质量因子小于1则会出现图像质量下降等情况。

相反,我建议回去并从Photos框架中获取原始资产。因此,在Swift 3中:

UIImagePNGRepresentation

如果你也必须支持iOS 7,你也可以使用等效的func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { if let url = info[UIImagePickerControllerReferenceURL] as? URL { let result = PHAsset.fetchAssets(withALAssetURLs: [url], options: nil) if let asset = result.firstObject { let manager = PHImageManager.default() manager.requestImageData(for: asset, options: nil) { imageData, dataUTI, orientation, info in if let fileURL = info!["PHImageFileURLKey"] as? URL { let filename = fileURL.lastPathComponent // use filename here } // use imageData here } } } picker.dismiss(animated: true) } API,但想法是一样的:获取原始资产而不是通过ALAssetsLibrary对其进行四舍五入。

(对于Swift 2的演绎,请参阅previous revision of this answer。)

答案 1 :(得分:0)

@Rob

的Swift 3版本答案
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let URL = info[UIImagePickerControllerReferenceURL] as? NSURL {
        let result = PHAsset.fetchAssets(withALAssetURLs: [URL as URL], options: nil)
        if let asset:PHAsset = result.firstObject! as PHAsset {
            let manager = PHImageManager.default()
            manager.requestImageData(for: asset, options: nil) { imageData, dataUTI, orientation, info in
                let fileURL = info!["PHImageFileURLKey"] as? NSURL
                let filename = fileURL?.lastPathComponent;

                // use imageData here
            }
        }
    }

    picker.dismiss(animated: true, completion: nil)

}

答案 2 :(得分:0)

另一种解决方案使用PHAssetResourceManager而不是PHImageManager。使用Xcode 10,Swift 4.2。

func imageFromResourceData(phAsset:PHAsset) {

    let assetResources = PHAssetResource.assetResources(for: phAsset)

    for resource in assetResources {

        if resource.type == PHAssetResourceType.photo {

            var imageData = Data()

            let options = PHAssetResourceRequestOptions()
            options.isNetworkAccessAllowed = true

            let _ = PHAssetResourceManager.default().requestData(for: resource, options: options, dataReceivedHandler: { (data:Data) in
                imageData.append(data)
            }, completionHandler: { (error:Error?) in
                if error == nil, let picked = UIImage(data: imageData) {
                    self.handlePickedImage(picked: picked)
                }
            })
        }

    }
}

像这样使用它:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

    dismiss(animated: true)

    let mediaType = info[UIImagePickerController.InfoKey.mediaType] as! NSString

    if mediaType == kUTTypeImage || mediaType == kUTTypeLivePhoto {

        if #available(iOS 11.0, *) {

            if let phAsset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
                self.imageFromResourceData(phAsset: phAsset)
            }
            else {
                if let picked = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) {
                    self.handlePickedImage(picked: picked)
                }
            }

        }
        else if let picked = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) {
            self.handlePickedImage(picked: picked)
        }
    }
}