UIImage in NSData konvertieren und in Swift wieder in UIImage konvertieren?

142

Ich versuche, ein UIImageto zu speichern NSDataund dann das NSDataBack to a new UIImagein Swift zu lesen . Um das UIImagein zu konvertieren , verwende NSDataich den folgenden Code:

let imageData: NSData = UIImagePNGRepresentation(myImage)

Wie konvertiere ich imageData(dh NSData) zurück in eine neue UIImage?

pete
quelle

Antworten:

155

UIImage(data:imageData,scale:1.0) Angenommen, der Maßstab des Bildes ist 1.

Verwenden Sie in Swift 4.2 den folgenden Code, um Data () abzurufen.

image.pngData()
Algen
quelle
66

Vielen Dank. Hat mir viel geholfen. Auf Swift 3 umgestellt und funktioniert

Speichern: let data = UIImagePNGRepresentation(image)

Laden: let image = UIImage(data: data)

Ivan Sinigaglia
quelle
1
Ist das nicht let imagePt = UIImage(data: caminhodaImagem)genug
Superarts.org
32

Verwenden Sie die imageWithData:Methode, die in Swift als übersetzt wirdUIImage(data:)

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

Jetzt können Sie in Swift 4.2 die pngData()neue Instanzmethode verwenden UIImage, um die Daten aus dem Image abzurufen

let profileImage = UIImage(named:"profile")!
let imageData = profileImage.pngData()
Sh_Khan
quelle
Ist Swift 4.2 in der Beta? Ich sehe diese Funktion nicht verfügbar
Daniel Springer
sieht aus wie es umbenannt wurde
吖 奇 说 - 何魏奇 Archy Will He
'pngData ()' wurde in 'UIImagePNGRepresentation (_ :)' umbenannt
j2abro
9

Einzelheiten

  • Xcode 10.2.1 (10E1001), Swift 5

Lösung 1

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

Lösung 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
        }
    }
}

Verwendung der Lösung 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")

Lösung 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
            }
        }
    }
}

Verwendung der Lösung 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)

Probleme

Die Bilddarstellung beansprucht viele CPU- und Speicherressourcen. In diesem Fall ist es also besser, mehrere Regeln zu befolgen:

- Führen Sie jpegData (compressQuality :) nicht in der Hauptwarteschlange aus

- Führen Sie nur eine jpegData (compressQuality :) gleichzeitig aus

Falsch:

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

Richtig:

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

Links

Wassili Bodnarchuk
quelle
Vasily, das war sehr hilfreich. Ich kann UIImages mit Ihrem Code in bmps konvertieren. Ich muss auch Alpha von bmp entfernen. Ich habe versucht, Optionen zum Entfernen des Alphas festzulegen und kann es scheinbar nicht dazu bringen, die Ebene zu entfernen. Ich rufe folgendermaßen auf: let options: NSDictionary = [kCGImagePropertyHasAlpha: false] let convertToBmp = image.toData (Optionen: Optionen, Typ: .bmp)
Gallaugher
@ Gallaugher bist du sicher, dass es nicht funktioniert? Versuchen Sie, ein PNG-Bild ohne Alpha zu erstellen, und überprüfen Sie es. Möglicherweise ist es unmöglich, die Eigenschaft kCGImagePropertyHasAlpha mit bmp zu verwenden.
Vasily Bodnarchuk
@ vasily-bodnarchuk Danke für den Hinweis (und früheren Code). Ich habe das Alpha losgeworden - ich konnte es nicht über png machen, aber ich habe resizedImage.toJpegData mit alpha als false verwendet, diese Daten dann wieder in ein UIImage konvertiert und dann ein toData vom Typ .bmp erstellt. Optionen hatten keine Auswirkungen, aber dies entfernte die Alpha-Ebene in Photoshop und erstellte eine kleinere Datei. Kann immer noch nicht das exakte 16-Bit-Raster-Grafik-BMP-Format erzeugen, das ich für ein PyPortal benötige. Aus irgendeinem Grund werden konvizierte Daten nicht angezeigt, wenn ich über ein Tool wie Online-Konvertierung konvertiere. Vielen Dank.
Gallaugher
@ vasily-bodnarchuk, der bmp, den ich mit Ihrem hilfreichen Code gespeichert habe, wird in Photoshop mit der bmp-Option "Zeilenreihenfolge spiegeln" geöffnet. Wenn ich diese Option auf dem Bildschirm "BMP-Optionen", der nach "Speichern unter ..." angezeigt wird, erneut speichere und deaktiviere, lade bmp auf das PyPortal, das aktualisierte bmp wird angezeigt. Ich sehe keine Apple-Dokumente, die wie eine Option "Zeilenreihenfolge spiegeln" aussehen. Ich bin mir nicht sicher, warum dies als Standardspeicher angezeigt wird, und ich bin mir nicht sicher, wie ich dies in Swift "rückgängig machen" soll. Übrigens: Ich habe meine Q & verwandten Dateien unter: stackoverflow.com/questions/57241391/… gepostet. Danke!
Gallaugher
8

So speichern Sie als Daten:

Wenn Sie in StoryBoard "Bild" -Daten in der Bildansicht von MainStoryBoard speichern möchten, funktionieren die folgenden Codes.

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

So laden Sie "image" in imageView: Sehen Sie sich das Ausrufezeichen "!", "?" genau, ob das ganz das gleiche ist wie dieses.

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

Der Typ "NSData" wird während dieses Vorgangs automatisch in den Typ "Daten" konvertiert.

zemunkh
quelle
6

Verwenden Sie für die sichere Ausführung von Code if-letblock with Data, um einen Absturz der App zu verhindern, da die Funktion UIImagePNGRepresentationeinen optionalen Wert zurückgibt.

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

Hinweis: Die Daten sind Swift 3+. Verwenden Sie mit Swift 3+ Daten anstelle von NSData

Generische Bildoperationen (wie png & jpg beide):

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

Mit der Erweiterung:

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
quelle
4

Bild zu Daten: -

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

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

Daten zum Bild: -

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

Swift 5

Lassen Sie das Bild, das Sie als UIImage erstellen, ein Bild sein

image.pngData() as NSData? 
Dakrawat
quelle
Bitte nehmen Sie sich einen Moment Zeit, um die Bearbeitungshilfe in der Hilfe durchzulesen . Die Formatierung beim Stapelüberlauf unterscheidet sich von anderen Websites.
Dharman