Obtenha NSData subjacente de UIImage

104

Eu posso criar UIImagea partir de NSDatausar [UIImage imageWithData:]ou[UIImage initWithData:] métodos.

Eu me pergunto se posso obter o NSDataretorno de um existente UIImage? Algo na linha deNSData *myData = [myImage getData];

Eugene
fonte

Respostas:

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

ou

NSData *imageData = UIImagePNGRepresentation(image);

Dependendo se você quiser seus dados no formato PNG ou JPG.

Caroline
fonte
82
Não sei por que essa resposta é votada tantas vezes, nem por que é aceita. O OP solicitou a recuperação dos dados fornecidos inicialmente. Usar UIImageJPEGRepresentationou UIImagePNGRepresentation irá alterar os dados e fazer uma reconversão. Existe alguma maneira de realmente alcançar o que foi pedido?
Patrik
6
Essa resposta não é boa, porque diminuirá a qualidade da imagem se ela já estiver em um formato com perdas.
1diaitwillmake
@CipherCom entendo o que você está dizendo sobre querer os dados exatos de volta. No entanto, acho que para a maioria das pessoas que encontram dúvidas, essa resposta será perfeita para suas necessidades ... daí os votos positivos. Se você encontrar uma resposta para obter os dados originais de volta, compartilhe;)
tybro0103
@ 1dayitwillmake Até o representante do PNG? Não é minha área de especialização, mas pensei que os PNGs não sofrem perdas.
tybro0103
@Bob Spryn Isso não vai ajudar. A propriedade CIImage só é definida se foi inicializada com imageWithCIImage :. Também não são diretamente os dados usados, mas sim outro objeto de representação de imagem.
King-Wizard de
21

Ao inicializar um UIImageobjeto com init(data: originalData), que originalDataserá convertido em dados brutos em algum tipo de formato interno. Esses dados podem ser recuperados posteriormente com

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

No entanto, como o rawDataé cru, será ainda maior do que quando usado UIImagePNGRepresentation.

Yesleon
fonte
como faço isso em Objective-C
h3dkandi 01 de
NSData * rawData = (__bridge NSData *) CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
ZardozSpeaks
@ZardozSpeaks a variante obj-c perfeitamente viável para ser incluída como uma edição nesta resposta.
Kamil.S
6

Você pode esperar que um UIImage seja um objeto formatado para exibição e, portanto, não estará usando os dados originais (que provavelmente estão no formato PNG ou JPEG), mas mais provavelmente uma matriz de pixels ou algum outro formato interno. Em outras palavras, UIImage(data: foo)não reterá foo.

  1. Se você quiser apenas usá-lo em outro lugar em seu programa, o UIImage original funcionará bem (presumo que não seja o caso aqui)

  2. Se você quiser serializar, UIImagePNGRepresentation(...)funcionará, mas ficará superdimensionado se o original for JPEG; UIImageJPEGRepresentation(...)frequentemente resultará em dados um pouco maiores e com perdas se o original for PNG. Não há problema em escolher um com base na forma como a imagem será exibida e no formato que você espera que seja fornecido. Se acontecer de você estar usando PNG e quiser sair do PNG, você deve obter um bom tamanho de arquivo e dados quase idênticos, pedaços especiais de PNG à parte.

  3. Se você deseja obter uma cópia exata dos dados originais (talvez para salvar um arquivo após a miniatura ou para SHA1), você precisa mantê-lo separadamente. Você pode fazer algo como:

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

Só porque me deparei com isso e gosto do Swift :)

Aqui está a tradução rápida do post de Caroiline.

var imageData = UIImagePNGRepresentation(image)

Ou

var imageData = UIImageJPEGRepresentation(image, 0.7) 
nsij22
fonte
A pergunta não era sobre rapidez.
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
fonte
-2

As coisas mudaram desde que a resposta acima foi dada, para aqueles que ainda procuram, porque compartilham da preocupação da CipherCom: o iOS 5 adicionou a propriedade CIImage .

Rafe
fonte
Não estou vendo uma maneira de usar CIImage para obter o NSData subjacente ... estou faltando alguma coisa?
tybro0103
4
Isso não vai ajudar. A propriedade CIImagesó é definida se foi inicializada com imageWithCIImage:. Também não são diretamente os dados usados, mas sim outro objeto de representação de imagem.
Patrik,