Ottieni NSData sottostante da UIImage


104

Posso creare UIImageda NSDatautilizzare [UIImage imageWithData:]o [UIImage initWithData:]metodi.

Mi chiedo se riesco a NSDatariprendermi da un esistente UIImage? Qualcosa sulla linea diNSData *myData = [myImage getData];

Risposte:


191
NSData *imageData = UIImageJPEGRepresentation(image, 0.7); // 0.7 is JPG quality

o

NSData *imageData = UIImagePNGRepresentation(image);

A seconda che tu voglia i tuoi dati in formato PNG o JPG.


82
Non so perché questa risposta sia stata votata così tante volte né perché sia ​​accettata. L'OP ha chiesto di recuperare i dati forniti inizialmente. Utilizzando UIImageJPEGRepresentationo UIImagePNGRepresentation si altera i dati e fare una riconversione. C'è un modo per ottenere davvero ciò che è stato chiesto?
Patrik

6
Questa risposta non è buona, perché abbasserà la qualità dell'immagine se è già in un formato con perdita di dati.
farà il

@CipherCom Capisco cosa stai dicendo sul voler indietro i dati esatti. Tuttavia, penso che per la maggior parte delle persone che incontrano domande, questa risposta sarà perfetta per le loro esigenze ... da qui i voti positivi. Se trovi una risposta per recuperare i dati originali, per favore condividi;)
tybro0103

@ 1dayitwillmake Even the PNG rep? Non è la mia area di competenza, ma pensavo che i PNG non subissero perdite?
tybro0103

@ Bob Spryn Questo non aiuterà. La proprietà CIImage viene impostata solo se è stata inizializzata con imageWithCIImage :. Inoltre questo non è direttamente i dati utilizzati ma piuttosto un altro oggetto di rappresentazione dell'immagine.
King-Wizard

21

Quando si inizializza un UIImageoggetto con init(data: originalData), questo originalDataverrà convertito in dati grezzi in una sorta di formato interno. Questi dati possono essere recuperati in seguito con

let rawData = myImage.cgImage?.dataProvider?.data as Data?

Tuttavia, poiché rawDataè grezzo, sarà ancora più grande di quando si utilizza UIImagePNGRepresentation.


come faccio a farlo in Objective-C
h3dkandi

NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks il

@ZardozSpeaks la variante obj-c perfettamente utilizzabile per essere inclusa come modifica in questa risposta.
Kamil.S

6

Puoi aspettarti che un UIImage sia un oggetto formattato per la visualizzazione e quindi non utilizzerà i dati originali (che sono probabilmente in formato PNG o JPEG) ma più probabilmente un array di pixel o qualche altro formato interno. In altre parole, UIImage(data: foo)non manterrà foo.

  1. Se vuoi solo usarlo altrove nel tuo programma, l'originale UIImage andrà bene (presumo che non sia effettivamente il caso qui)

  2. Se vuoi serializzare, UIImagePNGRepresentation(...)funzionerà ma sarà sovradimensionato se l'originale era un JPEG; UIImageJPEGRepresentation(...)spesso si tradurrà in dati leggermente sovradimensionati ed è leggermente con perdita se l'originale era PNG. Dovrebbe essere corretto sceglierne uno in base al modo in cui l'immagine verrà visualizzata e al formato che ci si aspetta venga fornito. Se ti capita di utilizzare PNG in e vuoi PNG fuori, dovresti ottenere una buona dimensione del file e dati quasi identici, blocchi PNG speciali a parte.

  3. Se si desidera ottenere una copia esatta dei dati originali (magari per salvare un file dopo l'anteprima o per SHA1), è necessario conservarlo separatamente. Potresti fare qualcosa come:

    var image:UIImage
    var imageData:NSData {
        didSet {
            image = UIImage(data: imageData)
        }
    }

4

Solo perché mi sono imbattuto in questo e mi piace Swift :)

Ecco la rapida traduzione del post di Caroiline.

var imageData = UIImagePNGRepresentation(image)

O

var imageData = UIImageJPEGRepresentation(image, 0.7) 

La domanda non riguardava la rapidità.
Cross_

3

Swift 4.2

let dataPng = image.pngData() // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format

let dataJpg = image.jpegData(compressionQuality: 1) // return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)

-2

Le cose sono cambiate da quando è stata data la risposta di cui sopra, per coloro che stanno ancora cercando perché condividono la preoccupazione di CipherCom: iOS 5 ha aggiunto la proprietà CIImage .


Non vedo un modo per utilizzare CIImage per ottenere il NSData sottostante ... mi manca qualcosa?
tybro0103

4
Questo non aiuta. La proprietà CIImageviene impostata solo se è stata inizializzata con imageWithCIImage:. Inoltre questo non è direttamente i dati utilizzati ma piuttosto un altro oggetto di rappresentazione dell'immagine.
Patrik
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.