Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When i am using UIImagePNGRepresentation or UIImageJPEGRepresentation for converting UIImage into NSdata, the image size is too much increased

Tags:

ios

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

like image 935
Govindarao Kondala Avatar asked Jan 19 '13 05:01

Govindarao Kondala


1 Answers

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

like image 76
foundry Avatar answered Nov 13 '22 06:11

foundry