When i am using UIImagePNGRepresentation or UIImageJPEGRepresentation for converting UIImage into NSdata, the image size is too much increased.
Steps to Reproduce:
1)Open Xcode and select new project as single view based application
2)Open ViewController.xib and add two buttons named as i)Test Online Image ii)Test Local image
3)Add two IBActions
i) -(IBAction)ClickLocalImageTest:(id)sender;
ii) -(IBAction)ClickOnLineImageTest:(id)sender;
4)Connect "Test Online Image" to "-(IBAction)ClickOnLineImageTest:(id)sender
"
and "Test Local image" to " -(IBAction)ClickLocalImageTest:(id)sender
;"
5)impalement "-(IBAction)ClickLocalImageTest:(id)sender
" method like as following
- (IBAction)ClickLocalImageTest:(id)sender {
NSLog(@"*************Test Local Image****************\n");
NSString *path=[[NSBundle mainBundle] pathForResource:@"hero_ipad_retina" ofType:@"jpg"];
NSLog(@"Before testing image size is :<---- %u kb",[[NSData dataWithContentsOfFile:path] length]/1024);
UIImage *img = [UIImage imageNamed:@"hero_ipad_retina.jpg"];
NSLog(@"UIImagePNGRepresentation: image size is---->: %u kb",[UIImagePNGRepresentation(img) length]/1024);
NSLog(@"UIImageJPEGRepresentation with scale 1.0: image size is---->: %u kb \n",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
NSLog(@"*************Completed test****************\n\n\n\n");
}
6) impalement "- (IBAction)ClickOnLineImageTest:(id)sender
" method as following
- (IBAction)ClickOnLineImageTest:(id)sender {
NSLog(@"*************Test Online Image****************\n");
NSLog(@"Before testing image size is :<---- %u kb",[[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://images.apple.com/home/images/hero_ipad_retina.jpg"]] length]/1024);
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://images.apple.com/home/images/hero_ipad_retina.jpg"]]];
NSLog(@"UIImagePNGRepresentation: image size is---->: %u kb",[UIImagePNGRepresentation(img) length]/1024);
NSLog(@"UIImageJPEGRepresentation with scale 1.0: image size is---->: %u kb \n",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
NSLog(@"*************Completed test****************\n\n\n\n");
}
7)Please download "hero_ipad_retina.jpg" image from here and save in your resources named as "hero_ipad_retina.jpg"
7)Now run this project on Xcode 4.0 later and IOS3.0 above SDK
**
Expected Results:
1)Click on "Test Online Image" button result should be as following
*************Test Online Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 78 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 78 kb
*************Completed test****************
2)1)Click on "Test Local image" button result should be as following
*************Test Local Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 78 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 78 kb
*************Completed test****************
Actual Results:
1)Click on "Test Online Image" button result should be as following
*************Test Online Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 480 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 180 kb
*************Completed test****************
2)1)Click on "Test Local image" button result should be as following
*************Test Local Image****************
Before testing image size is :<---- 78 kb
UIImagePNGRepresentation: image size is---->: 480 kb
UIImageJPEGRepresentation with scale 1.0: image size is---->: 180 kb
*************Completed test******************
My Question :
why it is increasing its size ? and what is the optimized way to convert image to NSData?
Notes: Please download "hero_ipad_retina.jpg" image from here and save in your resources
"hero_ipad_retina.jpg" is a compressed jpg image
This line:
[[NSData dataWithContentsOfFile:path] length]/1024
gives it's compressed file size...
This line:
[UIImagePNGRepresentation(img) length]/1024
uncompresses the image and converts it to PNG which is a lossless file format. It's size is inevitably much larger.
This line:
[UIImageJPEGRepresentation(img, 1.0) length]/1024
uncompresses the image and recompresses it to a JPG representation. You have set the quality to maximum (1.0) so - in comparison with the original which was no doubt compressed to lower quality - you get a larger file size. If you set quality to 0.5 you will get a small file size (around 42K)
This is a great reminder of why you should treat jpeg images with caution. Every time you access a jpeg imageRep, you are uncompressing. If you then recompress - even at full quality - you are downgrading the quality of the image (as each lossy compress is worse than the previous). Artefacts increase and become particularly noticeable with graphic images (flat colours, straight/contrasting edges). PNG is always safer - it is lossless at 24-bit, and at 8-bit is good at dealing with regions of flat colour.
update
To get the size of an image in memory:
NSUInteger sizeInBytes =
CGImageGetHeight(image.CGImage) * CGImageGetBytesPerRow(image.CGImage);
From this you can work out the compression ratios for PNG, JPG and the original file (divide by 1024 for kilobytes to get the correct ratios with the above figures).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With