convertir UIImage en NSData

170

J'utilise ce code dans mon application qui m'aidera à envoyer une image.

Cependant, j'ai une vue d'image avec une image. Je n'ai pas de fichier dans appbundle mais j'ai l'image de mon côté. Comment puis-je changer le code ci-dessous? Quelqu'un peut -il me dire comment puis - je convertir myimageà 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
la source
2
UIImageJPEGReprésentation, UIImagePNGRepresentation renvoient toutes les deux les nsdata de l'image .....
Himanshu Agnihotri

Réponses:

286

Essayez l'une des solutions suivantes, en fonction de votre format d'image:

UIImageJPEGRreprésentation

Renvoie les données de l'image spécifiée au format JPEG.

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

UIImagePNGReprésentation

Renvoie les données de l'image spécifiée au format PNG

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Voici les docs .

ÉDITER:

si vous souhaitez accéder aux octets bruts qui composent l'UIImage, vous pouvez utiliser cette approche:

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

Cela vous donnera la représentation de bas niveau des pixels RVB de l'image. (Omettez le CFBridgingReleasebit si vous n'utilisez pas ARC).

Sergio
la source
8
Existe-t-il un moyen d'obtenir simplement les données dans le format dans lequel elles se trouvent déjà?
devios1
1
Xcode me suggère d'utiliser (id)CFBridgingRelease(CGDataProviderCopyData(provider))pour prendre la propriété de CDataRefretourné par CGDataProviderCopyDatadans ARC.
mostruash
1
@mostruash: merci, j'ai modifié ma réponse pour tenir compte de votre suggestion.
sergio
@sergio Je n'ai pas d'expérience avec Obj-C non-ARC et je me demande si la publication dataserait suffisante ou s'il y aurait encore une fuite de mémoire.
mostruash
1
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
161
NSData *imageData = UIImagePNGRepresentation(myImage.image);
Base
la source
4
J'utilise cette ligne mais c'est très lent
user2128531
5
Notez que imageFlags (comme imageOrientation) est perdu lors de l'utilisation de UIImagePNGRepresentation. C'est pourquoi la présentation UIImageJPEGR est préférée.
Yony
26

Si vous avez une image dans une UIImageView, par exemple "myImageView", vous pouvez effectuer les opérations suivantes:

Convertissez votre image en utilisant UIImageJPEGRepresentation () ou UIImagePNGRepresentation () comme ceci:

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

Vous pouvez également placer ce code dans un bloc GCD et l'exécuter dans un autre thread, affichant un UIActivityIndicatorView pendant le processus ...

//*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
la source
24

Créez la référence de l'image ....

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

affichage de l'image dans la vue image ... imagedisplay est la référence de l'imageview:

imagedisplay.image = rainyImage;

convertissez-le en NSDataen passant une UIImageréférence et fournissez une qualité de compression en valeurs flottantes:

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

Solution dans Swift 4

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}
Charlton Provatas
la source
Comment les cgImage.dataProviderdonnées sont- elles encodées? Il semble être différent des données de UIImagePNGRepresentationet UIImageJPEGRepresentationparce qu'il ne peut pas être utilisé pour créer une image comme celle-ci UIImage(data: imageData).
Manuel
@Manuel Pas sûr. Je viens de convertir la syntaxe de la réponse de Sergio. Sergio le saurait probablement mieux.
Charlton Provatas
@Manuel Je suppose que parce qu'il utilise l'API CoreGraphics, il donne une représentation de données de plus bas niveau de l'image que ce que UIImageJPEGRepresentationfournit. Mais je pense que cette solution préserve le format d'encodage d'origine dans lequel se trouvait l'image et ne la réencode pas.
Charlton Provatas
1

Utilisez le bloc if-let avec Data pour empêcher le blocage de l'application et l'exécution sûre du code, car la fonction UIImagePNGRepresentation renvoie une valeur facultative.

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

Remarque: les données sont de classe Swift 3. Utilisez des données au lieu de NSData avec Swift 3

Opérations génériques sur les images (comme png et jpg les deux):

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

En utilisant l'extension:

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
la source
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
la source