Convertir UIImage a NSData y convertir de nuevo a UIImage en Swift?

142

Estoy tratando de salvar una UIImagea NSDatay después lee el NSDataregreso a un nuevo UIImageen Swift. Para convertir UIImagea NSDataestoy usando el siguiente código:

let imageData: NSData = UIImagePNGRepresentation(myImage)

¿Cómo convierto imageData(es decir, NSData) de nuevo a un nuevo UIImage?

pete
fuente

Respuestas:

155

UIImage(data:imageData,scale:1.0) suponiendo que la escala de la imagen es 1.

En swift 4.2, use el siguiente código para obtener datos ().

image.pngData()
alga
fuente
66

Gracias. Me ayudo mucho. Convertido a Swift 3 y trabajado

Ahorrar: let data = UIImagePNGRepresentation(image)

Cargar: let image = UIImage(data: data)

Ivan Sinigaglia
fuente
1
¿No es let imagePt = UIImage(data: caminhodaImagem)suficiente?
superarts.org
32

Use el imageWithData:método, que se traduce a Swift comoUIImage(data:)

let image : UIImage = UIImage(data: imageData)
dasblinkenlight
fuente
17

Ahora en Swift 4.2 puede usar un pngData()nuevo método de instancia UIImagepara obtener los datos de la imagen

let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()
Sh_Khan
fuente
¿Swift 4.2 está en beta? No veo esta función disponible
Daniel Springer
parece que ha sido renombrado
吖 奇 说 - 何魏奇 Archy Will He
'pngData ()' ha cambiado de nombre a 'UIImagePNGRepresentation (_ :)'
j2abro
9

Detalles

  • Xcode 10.2.1 (10E1001), Swift 5

Solución 1

guard let image = UIImage(named: "img") else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
let pngData = image.pngData()

Solución 2.1

extension UIImage {
    func toData (options: NSDictionary, type: CFString) -> Data? {
        guard let cgImage = cgImage else { return nil }
        return autoreleasepool { () -> Data? in
            let data = NSMutableData()
            guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
            CGImageDestinationAddImage(imageDestination, cgImage, options)
            CGImageDestinationFinalize(imageDestination)
            return data as Data
        }
    }
}

Uso de la solución 2.1

// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
let options: NSDictionary =     [
    kCGImagePropertyOrientation: 6,
    kCGImagePropertyHasAlpha: true,
    kCGImageDestinationLossyCompressionQuality: 0.5
]

// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
guard let data = image.toData(options: options, type: kUTTypeJPEG) else { return }
let size = CGFloat(data.count)/1000.0/1024.0
print("\(size) mb")

Solución 2.2

extension UIImage {

    func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
        guard cgImage != nil else { return nil }
        let options: NSDictionary =     [
                                            kCGImagePropertyOrientation: orientation,
                                            kCGImagePropertyHasAlpha: hasAlpha,
                                            kCGImageDestinationLossyCompressionQuality: compressionQuality
                                        ]
        return toData(options: options, type: .jpeg)
    }

    func toData (options: NSDictionary, type: ImageType) -> Data? {
        guard cgImage != nil else { return nil }
        return toData(options: options, type: type.value)
    }
    // about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
    func toData (options: NSDictionary, type: CFString) -> Data? {
        guard let cgImage = cgImage else { return nil }
        return autoreleasepool { () -> Data? in
            let data = NSMutableData()
            guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
            CGImageDestinationAddImage(imageDestination, cgImage, options)
            CGImageDestinationFinalize(imageDestination)
            return data as Data
        }
    }

    // https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
    enum ImageType {
        case image // abstract image data
        case jpeg                       // JPEG image
        case jpeg2000                   // JPEG-2000 image
        case tiff                       // TIFF image
        case pict                       // Quickdraw PICT format
        case gif                        // GIF image
        case png                        // PNG image
        case quickTimeImage             // QuickTime image format (OSType 'qtif')
        case appleICNS                  // Apple icon data
        case bmp                        // Windows bitmap
        case ico                        // Windows icon data
        case rawImage                   // base type for raw image data (.raw)
        case scalableVectorGraphics     // SVG image
        case livePhoto                  // Live Photo

        var value: CFString {
            switch self {
            case .image: return kUTTypeImage
            case .jpeg: return kUTTypeJPEG
            case .jpeg2000: return kUTTypeJPEG2000
            case .tiff: return kUTTypeTIFF
            case .pict: return kUTTypePICT
            case .gif: return kUTTypeGIF
            case .png: return kUTTypePNG
            case .quickTimeImage: return kUTTypeQuickTimeImage
            case .appleICNS: return kUTTypeAppleICNS
            case .bmp: return kUTTypeBMP
            case .ico: return kUTTypeICO
            case .rawImage: return kUTTypeRawImage
            case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
            case .livePhoto: return kUTTypeLivePhoto
            }
        }
    }
}

Uso de la solución 2.2

let compressionQuality: CGFloat = 0.4
guard let data = image.toJpegData(compressionQuality: compressionQuality) else { return }
printSize(of: data)

let options: NSDictionary =     [
                                    kCGImagePropertyHasAlpha: true,
                                    kCGImageDestinationLossyCompressionQuality: compressionQuality
                                ]
guard let data2 = image.toData(options: options, type: .png) else { return }
printSize(of: data2)

Problemas

La representación de imágenes requerirá muchos recursos de CPU y memoria. Entonces, en este caso, es mejor seguir varias reglas:

- no ejecute jpegData (compressQuality :) en la cola principal

- ejecute solo un jpegData (compressQuality :) simultáneamente

Incorrecto:

for i in 0...50 {
    DispatchQueue.global(qos: .utility).async {
        let quality = 0.02 * CGFloat(i)
        //let data = image.toJpegData(compressionQuality: quality)
        let data = image.jpegData(compressionQuality: quality)
        let size = CGFloat(data!.count)/1000.0/1024.0
        print("\(i), quality: \(quality), \(size.rounded()) mb")
    }
}

Correcto:

let serialQueue = DispatchQueue(label: "queue", qos: .utility, attributes: [], autoreleaseFrequency: .workItem, target: nil)

for i in 0...50 {
    serialQueue.async {
        let quality = 0.02 * CGFloat(i)
        //let data = image.toJpegData(compressionQuality: quality)
        let data = image.jpegData(compressionQuality: quality)
        let size = CGFloat(data!.count)/1000.0/1024.0
        print("\(i), quality: \(quality), \(size.rounded()) mb")
    }
}

Enlaces

Vasily Bodnarchuk
fuente
Vasily, esto fue de gran ayuda. Puedo convertir UIImages a bmps usando su código. También necesito eliminar alfa de bmp. Intenté establecer opciones para eliminar el alfa y parece que no puedo obtenerlo para deshacerme de la capa. Llamo así: opciones de let: NSDictionary = [kCGImagePropertyHasAlpha: false] let convertToBmp = image.toData (opciones: opciones, tipo: .bmp)
Gallaugher
@Gallaugher, ¿estás seguro de que no funciona? Intenta crear una imagen png sin alfa y compruébalo. Puede ser imposible usar la propiedad kCGImagePropertyHasAlpha con bmp.
Vasily Bodnarchuk
@ vasily-bodnarchuk Gracias por el plomo (y el código anterior). Me deshice del alfa: no pude hacerlo a través de png, pero usé resizedImage.toJpegData con alfa como falso, luego convertí estos datos nuevamente en un UIImage, luego hice un toData de tipo .bmp. Las opciones no tuvieron impacto, pero esto eliminó la capa alfa en Photoshop y creó un archivo más pequeño. Todavía no puedo producir el formato bmp gráfico de trama exacto de 16 bits que necesito para un PyPortal. Por alguna razón, los datos convencedos no se muestran por hace cuando convierto a través de una herramienta como conversión en línea. Gracias.
Gallaugher
@ vasily-bodnarchuk, el bmp que he guardado con su útil código se abre en Photoshop con la opción bmp "Voltear orden de fila". Si vuelvo a guardar y desmarco esta opción en la pantalla "Opciones BMP" que aparece después de "Guardar como ...", entonces cargue bmp en PyPortal, muestra bmp actualizado. No veo ningún documento de Apple que parezca una opción de "Orden de fila invertida", no estoy seguro de por qué esto aparece como el guardado predeterminado y no estoy seguro de cómo "deshacer" esto en Swift. Por cierto: he publicado mi Q y archivos relacionados en: stackoverflow.com/questions/57241391/… ¡Gracias!
Gallaugher
8

Para guardar como datos:

Desde StoryBoard, si desea guardar datos de "imagen" en la imageView de MainStoryBoard, los siguientes códigos funcionarán.

let image = UIImagePNGRepresentation(imageView.image!) as NSData?

Para cargar "imagen" en imageView: Mire el signo de exclamación "!", "?" de cerca si eso es lo mismo que este.

imageView.image = UIImage(data: image as! Data)

El tipo "NSData" se convierte automáticamente en el tipo "Datos" durante este proceso.

zemunkh
fuente
6

Para una ejecución segura del código, use if-letblock with Datapara evitar el bloqueo de la aplicación &, ya que la función UIImagePNGRepresentationdevuelve un valor opcional.

if let img = UIImage(named: "TestImage.png") {
    if let data:Data = UIImagePNGRepresentation(img) {
       // Handle operations with data here...         
    }
}

Nota: Los datos son de clase Swift 3+. Use datos en lugar de NSData con Swift 3+

Operaciones genéricas de imagen (como png y jpg ambas):

if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
        if let data:Data = UIImagePNGRepresentation(img) {
               handleOperationWithData(data: data)     
        } else if let data:Data = UIImageJPEGRepresentation(img, 1.0) {
               handleOperationWithData(data: data)     
        }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}

Mediante el uso de la extensión:

extension UIImage {

    var pngRepresentationData: Data? {
        return UIImagePNGRepresentation(self)
    }

    var jpegRepresentationData: Data? {
        return UIImageJPEGRepresentation(self, 1.0)
    }
}

*******
if let img = UIImage(named: "TestImage.png") {  //UIImage(named: "TestImage.jpg")
      if let data = img.pngRepresentationData {
              handleOperationWithData(data: data)     
      } else if let data = img.jpegRepresentationData {
              handleOperationWithData(data: data)     
     }
}

*******
func handleOperationWithData(data: Data) {
     // Handle operations with data here...
     if let image = UIImage(data: data) {
        // Use image...
     }
}
Krunal
fuente
4

Imagen a datos: -

    if let img = UIImage(named: "xxx.png") {
        let pngdata = img.pngData()
    }

   if let img = UIImage(named: "xxx.jpeg") {
        let jpegdata = img.jpegData(compressionQuality: 1)
    }

Datos a la imagen: -

 let image = UIImage(data: pngData)
Yogendra Singh
fuente
1

Swift 5

deja que la imagen que crees como UIImage sea imagen

image.pngData() as NSData? 
dakrawat
fuente
Tómese un momento para leer la ayuda de edición en el centro de ayuda . El formateo en Stack Overflow es diferente al de otros sitios.
Dharman