Obtener NSData subyacente de UIImage

104

Puedo crear UIImagede NSDatausar [UIImage imageWithData:]o [UIImage initWithData:]métodos.

Me pregunto si puedo NSDatarecuperarme de un existente UIImage. Algo en la linea deNSData *myData = [myImage getData];

Eugenio
fuente

Respuestas:

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

o

NSData *imageData = UIImagePNGRepresentation(image);

Dependiendo de si quieres tus datos en formato PNG o JPG.

carolino
fuente
82
No sé por qué esta respuesta es votada tantas veces ni por qué se acepta. El OP solicitó recuperar los datos que se le dieron inicialmente. El uso UIImageJPEGRepresentationo UIImagePNGRepresentation va a alterar los datos y hacer una reconversión. ¿Existe alguna forma de lograr realmente lo que se pidió?
Patrik
6
Esta respuesta no es buena, porque reducirá la calidad de la imagen si ya está en un formato con pérdida.
1día se hará el
@CipherCom Veo lo que está diciendo acerca de querer recuperar los datos exactos. Sin embargo, creo que para la mayoría de las personas que se encuentran con la pregunta, esta respuesta será perfecta para sus necesidades ... de ahí los votos a favor. Si encuentra una respuesta para recuperar los datos originales, compártala;)
tybro0103
@ 1dayitwillmake ¿Incluso el representante de PNG? No es mi área de especialización, pero pensé que los PNG no sufren pérdidas.
tybro0103
@Bob Spryn Esto no ayudará. La propiedad CIImage solo se establece si se inicializó con imageWithCIImage :. Además, estos no son directamente los datos utilizados, sino otro objeto de representación de imágenes.
King-Wizard
21

Al inicializar un UIImageobjeto con init(data: originalData), eso originalDatase convertirá en datos sin procesar en algún tipo de formato interno. Estos datos se pueden recuperar más tarde con

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

Sin embargo, debido a que rawDataestá crudo, será incluso más grande que cuando se usa UIImagePNGRepresentation.

yesleon
fuente
¿Cómo hago esto en Objective-C?
h3dkandi
NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks
@ZardozSpeaks que la variante obj-c es perfectamente viable para ser incluida como edición en esta respuesta.
Kamil.S
6

Puede esperar que un UIImage sea un objeto formateado para su visualización y, por lo tanto, no utilizará los datos originales (que probablemente estén en formato PNG o JPEG), sino más bien una matriz de píxeles o algún otro formato interno. En otras palabras,UIImage(data: foo) no retendrá foo.

  1. Si solo desea usarlo en otra parte de su programa, el UIImage original funcionará bien (supongo que ese no es el caso aquí)

  2. Si desea serializar, UIImagePNGRepresentation(...)funcionará pero será demasiado grande si el original era un JPEG;UIImageJPEGRepresentation(...)a menudo resultará en datos ligeramente sobredimensionados y con pérdidas si el original era PNG. Debería estar bien elegir uno según la forma en que se mostrará la imagen y el formato que espera que se le proporcione. Si está usando PNG dentro y quiere PNG fuera, debe obtener un buen tamaño de archivo y datos casi idénticos, aparte de los fragmentos especiales de PNG.

  3. Si desea obtener una copia exacta de los datos originales (tal vez para guardar un archivo después de la miniatura o para SHA1), debe conservarlo por separado. Podrías hacer algo como:

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

Solo porque me topé con esto y me gusta Swift :)

Aquí está la rápida traducción de la publicación de Caroiline.

var imageData = UIImagePNGRepresentation(image)

O

var imageData = UIImageJPEGRepresentation(image, 0.7) 
nsij22
fuente
La pregunta no se trataba de rápido.
Cross_
3

Rápido 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
fuente
-2

Las cosas han cambiado desde que se dio la respuesta anterior, para aquellos que todavía buscan porque comparten la preocupación de CipherCom: iOS 5 ha agregado la propiedad CIImage .

Rafe
fuente
No veo una forma de usar CIImage para obtener el NSData subyacente ... ¿Me estoy perdiendo algo?
tybro0103
4
Esto no ayudará. La propiedad CIImagesolo se establece si se inicializó con imageWithCIImage:. Además, estos no son directamente los datos utilizados, sino otro objeto de representación de imágenes.
Patrik