UIImageView no muestra transparencia de imágenes PNG de UIImagePickerController

Seguramente espero haber perdido algo porque no entiendo por qué funciona de la manera en que lo hace. Tengo una image PNG, que tiene un background totalmente transparente porque quiero superponerlo en otras imágenes dentro de UIImageView .

Las imágenes PNG incluidas en el proyecto XCode funcionan bien como deberían. El problema es cuando selecciono estas mismas imágenes PNG sobre la marcha usando UIImagePickerController y luego asignándolas a la UIImageView , por alguna razón realmente extraña, no la respeta como una image PNG con transparencia y en su lugar agrega un background blanco.

¿Alguien ha visto esto antes y cómo soluciono esto?

* ACTUALIZACIÓN # 1: Decidí probar algo que parece confirmar mi teoría. Decidí enviarme por correo electrónico las imágenes PNG originales que guardé en mi dispositivo y he aquí, las imágenes me llegaron como JPG. Me parece que cuando guardas una image en Photos en iPhone la convierte a JPG, esto es bastante impactante para mí. Espero que alguien tenga una forma de evitar esto. Las imágenes originales testImage1.png y testImage2.png guardadas en Fotos y luego enviadas por correo electrónico a mí mismo, regresaron como IMG_XXXX.jpg y IMG_XXXX.jpg

* ACTUALIZACIÓN # 2: Seguí jugando con esto más y descubrí algunas cosas y en el process pude responder mi propia pregunta. (1) Mi teoría en ACTUALIZACIÓN # 1 es parcialmente correcta, pero la conversión no ocurre al save la foto, parece que está sobre la marcha. Internamente, las fotos almacenan la extensión de la image original (2) Pude validar esto cuando me di count en mi UIImagePickerControllerDelegate que estaba usando

 let imageData = UIImageJPEGRepresentation(image, 1.0) 

en lugar de esto

 let imageData = UIImagePNGRepresentation(image) 

Cuando utilicé la segunda línea de código, estaba reconociendo las properties de transparencia originales para la image.

Sí, la llamada a UIImageJPEGRepresentation convertirá la image resultante en un JPEG, que no admite transparencia.

Por cierto, si su intención es get NSData para la image por otros motivos (p. UIImagePNGRepresentation ., UIImagePNGRepresentation al server, enviar correos electrónicos, etc.), yo recomendaría en contra de UIImageJPEGRepresentation y UIImagePNGRepresentation . Pierden metadatos, pueden hacer que el activo sea más grande, si sufre alguna degradación de image si utiliza un factor de calidad inferior a 1, etc.

En cambio, recomiendo volver y get el recurso original del marco de fotos. Por lo tanto, en Swift 3:

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

Si también tiene que admitir iOS 7, usaría la API equivalente de ALAssetsLibrary , pero la idea es la misma: ALAssetsLibrary el activo original en lugar de dispararlo a través de un UIImage .

(Para la versión Swift 2, ver la revisión anterior de esta respuesta ).

Versión Swift 3 de la respuesta de @Rob

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