Obtenir les NSData sous-jacents à partir d'UIImage

104

Je peux créer UIImageà l' NSDataaide de méthodes [UIImage imageWithData:]ou [UIImage initWithData:].

Je me demande si je peux récupérer le NSDatados d'un existant UIImage? Quelque chose sur la ligne deNSData *myData = [myImage getData];

Eugène
la source

Réponses:

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

ou

NSData *imageData = UIImagePNGRepresentation(image);

Selon si vous souhaitez que vos données soient au format PNG ou JPG.

Caroline
la source
82
Je ne sais pas pourquoi cette réponse est votée autant de fois ni si elle est acceptée. Le PO a demandé de récupérer les données initialement fournies. L' utilisation UIImageJPEGRepresentationou UIImagePNGRepresentation va modifier les données et faire un reconversions. Existe-t-il un moyen de vraiment réaliser ce qui a été demandé?
Patrik
6
Cette réponse n'est pas bonne, car elle diminuera la qualité de l'image si elle est déjà dans un format avec perte.
jour, le
@CipherCom Je vois ce que vous dites sur le fait de vouloir récupérer les données exactes. Cependant, je pense que pour la majorité des personnes qui rencontrent des questions, cette réponse sera parfaite pour leurs besoins ... d'où les votes positifs. Si vous trouvez une réponse pour récupérer les données originales, veuillez la partager;)
tybro0103
@ 1dayitwillmake Même le représentant PNG? Ce n'est pas mon domaine d'expertise, mais je pensais que les PNG ne subissaient pas de perte?
tybro0103
@Bob Spryn Cela n'aidera pas. La propriété CIImage n'est définie que si elle a été initialisée avec imageWithCIImage :. De plus, ce ne sont pas directement les données utilisées mais plutôt un autre objet de représentation d'image.
King-Wizard
21

Lors de l'initialisation d'un UIImageobjet avec init(data: originalData), cela originalDatasera converti en données brutes dans une sorte de format interne. Ces données peuvent être récupérées ultérieurement avec

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

Cependant, comme il rawDataest brut, il sera encore plus gros que lors de l'utilisation UIImagePNGRepresentation.

yesleon
la source
comment faire cela en Objective-C
h3dkandi
NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks
@ZardozSpeaks la variante obj-c parfaitement viable pour être incluse en tant que modification dans cette réponse.
Kamil.S
6

Vous pouvez vous attendre à ce qu'une UIImage soit un objet formaté pour l'affichage et n'utilisera donc pas les données d'origine (qui sont probablement au format PNG ou JPEG) mais plus probablement un tableau de pixels ou un autre format interne. En d'autres termes, UIImage(data: foo)ne retiendra pas foo.

  1. Si vous souhaitez simplement l'utiliser ailleurs dans votre programme, l'UIImage d'origine fera l'affaire (je suppose que ce n'est pas le cas ici)

  2. Si vous souhaitez sérialiser, UIImagePNGRepresentation(...)fonctionnera mais sera surdimensionné si l'original était un JPEG; UIImageJPEGRepresentation(...)entraînera souvent des données légèrement surdimensionnées et est légèrement avec perte si votre original était PNG. Vous devriez en choisir un en fonction de la façon dont l'image sera affichée et du format que vous prévoyez de fournir. Si vous utilisez PNG et que vous voulez que PNG sort, vous devriez obtenir une bonne taille de fichier et des données presque identiques, à part les morceaux PNG spéciaux.

  3. Si vous souhaitez obtenir une copie exacte des données d'origine (peut-être pour enregistrer un fichier après la vignette ou pour le SHA1), vous devez le conserver séparément. Vous pourriez faire quelque chose comme:

    var image:UIImage
    var imageData:NSData {
        didSet {
            image = UIImage(data: imageData)
        }
    }
Jim Driscoll
la source
4

Juste parce que je suis tombé dessus et que j'aime Swift :)

Voici la traduction rapide du message de Caroiline.

var imageData = UIImagePNGRepresentation(image)

Ou

var imageData = UIImageJPEGRepresentation(image, 0.7) 
nsij22
la source
La question n'était pas rapide.
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)
Maslovsa
la source
-2

Les choses ont changé depuis que la réponse ci-dessus a été donnée, pour ceux qui cherchent toujours parce qu'ils partagent la préoccupation de CipherCom: iOS 5 a ajouté la propriété CIImage .

Rafe
la source
Je ne vois pas de moyen d'utiliser CIImage pour obtenir le NSData sous-jacent ... est-ce que je manque quelque chose?
tybro0103
4
Cela n'aidera pas. La propriété CIImagen'est définie que si elle a été initialisée avec imageWithCIImage:. De plus, ce ne sont pas directement les données utilisées mais plutôt un autre objet de représentation d'image.
Patrik