convertir UIImage a NSData

170

Estoy usando este código en mi aplicación que me ayudará a enviar una imagen.

Sin embargo, tengo una vista de imagen con una imagen. No tengo ningún archivo en appbundle pero tengo la imagen a mi lado. ¿Cómo puedo cambiar el siguiente código? ¿Puede alguien decirme cómo puedo convertir myimagea NSData?

// Attach an image to the email
NSString *path = [[NSBundle mainBundle] pathForResource:@"rainy" ofType:@"jpg"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:@"image/jpeg" fileName:@"rainy"];
Christina
fuente
2
UIImageJPEGRepresentation, UIImagePNGRepresentation ambos devuelven nsdata de la imagen .....
Himanshu Agnihotri

Respuestas:

286

Pruebe uno de los siguientes, según su formato de imagen:

UIImageJPEGRepresentation

Devuelve los datos de la imagen especificada en formato JPEG.

NSData * UIImageJPEGRepresentation (
   UIImage *image,
   CGFloat compressionQuality
);

UIImagePNGRepresentation

Devuelve los datos para la imagen especificada en formato PNG

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Aquí los documentos .

EDITAR:

Si desea acceder a los bytes sin procesar que componen el UIImage, puede utilizar este enfoque:

CGDataProviderRef provider = CGImageGetDataProvider(image.CGImage);
NSData* data = (id)CFBridgingRelease(CGDataProviderCopyData(provider));
const uint8_t* bytes = [data bytes];

Esto le dará la representación de bajo nivel de los píxeles RGB de la imagen. (Omita el CFBridgingReleasebit si no está utilizando ARC).

sergio
fuente
8
¿Hay alguna manera de obtener los datos en cualquier formato en el que ya estén?
devios1
1
Xcode me sugiere que use (id)CFBridgingRelease(CGDataProviderCopyData(provider))para tomar la propiedad de CDataRefdevuelto por CGDataProviderCopyDataARC.
mostruash
1
@mostruash: gracias, he modificado mi respuesta para tener en cuenta su sugerencia.
sergio
@sergio No tengo experiencia con Obj-C que no sea ARC y me pregunto si liberarlo datasería suficiente o si todavía habría una pérdida de memoria.
mostruash
1
Esto no ayudará. La propiedad CIImage solo se establece si se inicializó con imageWithCIImage :. Además, esto no es directamente los datos utilizados, sino más bien otro objeto de representación de imágenes.
King-Wizard
161
NSData *imageData = UIImagePNGRepresentation(myImage.image);
Base
fuente
44
Estoy usando esta línea, pero esto es muy lento
user2128531
55
Tenga en cuenta que imageFlags (como imageOrientation) se pierden al usar UIImagePNGRepresentation. Es por eso que se prefiere la representación UIImageJPEG.
Yony
26

Si tiene una imagen dentro de un UIImageView, por ejemplo, "myImageView", puede hacer lo siguiente:

Convierta su imagen usando UIImageJPEGRepresentation () o UIImagePNGRepresentation () de esta manera:

NSData *data = UIImagePNGRepresentation(myImageView.image);
//or
NSData *data = UIImageJPEGRepresentation(myImageView.image, 0.8);
//The float param (0.8 in this example) is the compression quality 
//expressed as a value from 0.0 to 1.0, where 1.0 represents 
//the least compression (or best quality).

También puede poner este código dentro de un bloque GCD y ejecutarlo en otro subproceso, mostrando un UIActivityIndicatorView durante el proceso ...

//*code to show a loading view here*

dispatch_queue_t myQueue = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(myQueue, ^{ 

    NSData *data = UIImagePNGRepresentation(myImageView.image);
    //some code....

    dispatch_async( dispatch_get_main_queue(), ^{
        //*code to hide the loading view here*
    });
});
FormigaNinja
fuente
24

Crea la referencia de imagen ....

UIImage *rainyImage = [UIImage imageNamed:@"rainy.jpg"];

mostrar imagen en la vista de imagen ... imagedisplay es referencia de imageview:

imagedisplay.image = rainyImage;

conviértalo NSDatapasando la UIImagereferencia y proporcione calidad de compresión en valores flotantes:

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);
Jemythehigh
fuente
2

Solución en Swift 4

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}
Charlton Provatas
fuente
¿Cómo se cgImage.dataProvidercodifican los datos? Parece ser diferente de los datos de UIImagePNGRepresentationy UIImageJPEGRepresentationporque no se puede usar para crear una imagen como esta UIImage(data: imageData).
Manuel
@Manuel No estoy seguro. Acabo de convertir la sintaxis de la respuesta de Sergio. Sergio probablemente lo sabría mejor.
Charlton Provatas
@Manuel Supongo que porque está usando CoreGraphics API está dando una representación de datos de nivel inferior de la imagen de lo que UIImageJPEGRepresentationproporciona. Pero creo que esta solución conserva el formato de codificación original en el que estaba la imagen y no la vuelve a codificar.
Charlton Provatas
1

Use el bloque if-let con datos para evitar el bloqueo de la aplicación y la ejecución segura del código, ya que la función UIImagePNGRepresentation devuelve un valor opcional.

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

Nota: Los datos son de la clase Swift 3. Use datos en lugar de NSData con Swift 3

Operaciones genéricas de imagen (como png y jpg ambas):

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

Mediante el uso de la extensión:

extension UIImage {

    var pngRepresentationData: Data? {
        return UIImagePNGRepresentation(img)
    }

    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
fuente
0
- (void) imageConvert
{
     UIImage *snapshot = self.myImageView.image;
     [self encodeImageToBase64String:snapshot];
}    


call this method for image convert in base 64 
    -(NSString *)encodeImageToBase64String:(UIImage *)image
    {
        return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    }
Jayesh Mardiya
fuente