177

I am using this code in my app which will help me to send a image.

However, I have an image view with an image. I have no file in appbundle but have the image in my side. How can I change the below code ? Can anyone tell me how can I convert myimage to 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"];
Arnaud
  • 7,259
  • 10
  • 50
  • 71
Vipin
  • 4,718
  • 12
  • 54
  • 81

7 Answers7

289

Try one of the following, depending on your image format:

UIImageJPEGRepresentation

Returns the data for the specified image in JPEG format.

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

UIImagePNGRepresentation

Returns the data for the specified image in PNG format

NSData * UIImagePNGRepresentation (
   UIImage *image
);

Here the docs.

EDIT:

if you want to access the raw bytes that make up the UIImage, you could use this approach:

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

This will give you the low-level representation of the image RGB pixels. (Omit the CFBridgingRelease bit if you are not using ARC).

Cœur
  • 37,241
  • 25
  • 195
  • 267
sergio
  • 68,819
  • 11
  • 102
  • 123
  • 9
    Is there a way to just get the data in whatever format it is already in? – devios1 Sep 14 '13 at 18:19
  • 1
    Xcode suggests me to use `(id)CFBridgingRelease(CGDataProviderCopyData(provider))` to take the ownership of `CDataRef` returned by `CGDataProviderCopyData` in ARC. – mostruash Jan 17 '14 at 12:42
  • 1
    @mostruash: thanks, I have modified my answer to take into account your suggestion. – sergio Jan 17 '14 at 14:52
  • @sergio I'm not experienced with non-ARC Obj-C and I wonder if releasing `data` would be enough or if there would still be a memory leak. – mostruash Jan 17 '14 at 15:15
  • @mostruash: in non-ARC case, there is no concept of ownership; the programmer should ensure that each object be released for any retain it received. In the present case, by releasing `data` you would ensure the object is properly deallocated: `CGDataProviderCopyData` gives you a retain count of `1`; be releasing the object, you make it to be dealloc-ed. – sergio Jan 17 '14 at 15:48
  • Note that imageFlags (like imageOrientation) get lost when using UIImagePNGRepresentation. That's why UIImageJPEGRepresentation is preferred – Yony Nov 01 '14 at 07:34
  • 1
    This won't help. The property CIImage is only set if it was initialized with imageWithCIImage:. Also this isn't directly the used data but rather another image representation object. – King-Wizard Mar 18 '15 at 09:45
166
NSData *imageData = UIImagePNGRepresentation(myImage.image);
Renjith
  • 5,783
  • 9
  • 31
  • 42
Radix
  • 3,639
  • 3
  • 31
  • 47
26

If you have an image inside a UIImageView , e.g. "myImageView", you can do the following:

Convert your image using UIImageJPEGRepresentation() or UIImagePNGRepresentation() like this:

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

You can also put this code inside a GCD block and execute in another thread, showing an UIActivityIndicatorView during the process ...

//*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*
    });
});
Efren
  • 4,003
  • 4
  • 33
  • 75
FormigaNinja
  • 1,571
  • 1
  • 24
  • 36
24

Create the reference of image....

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

displaying image in image view... imagedisplay is reference of imageview:

imagedisplay.image = rainyImage;

convert it into NSData by passing UIImage reference and provide compression quality in float values:

NSData *imgData = UIImageJPEGRepresentation(rainyImage, 0.9);
ChikabuZ
  • 10,031
  • 5
  • 63
  • 86
Jemythehigh
  • 583
  • 5
  • 12
2

Solution in Swift 4

extension UIImage {
    var data : Data? {
      return cgImage?.dataProvider?.data as Data?
    }
}
Charlton Provatas
  • 2,184
  • 25
  • 18
  • How is the `cgImage.dataProvider` data encoded? It seems to be different from the data of `UIImagePNGRepresentation` and `UIImageJPEGRepresentation` because it cannot be used to create an image like so `UIImage(data: imageData)`. – Manuel Nov 17 '17 at 11:56
  • @Manuel Not sure. I just converted the syntax from Sergio 's answer. Sergio would probably know better. – Charlton Provatas Nov 17 '17 at 12:52
  • @Manuel I'm assuming because it's using CoreGraphics API it's giving a lower-level data representation of the image than what `UIImageJPEGRepresentation` provides. But I believe this solution preserves the original encoding format that the image was in and doesn't re-encode it. – Charlton Provatas Nov 17 '17 at 12:55
1

Use if-let block with Data to prevent app crash & safe execution of code, as function UIImagePNGRepresentation returns an optional value.

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

Note: Data is Swift 3 class. Use Data instead of NSData with Swift 3

Generic image operations (like png & jpg both):

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

By using 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
  • 77,632
  • 48
  • 245
  • 261
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
  • 770
  • 7
  • 17