Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

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

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****************
");
    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 
",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
    NSLog(@"*************Completed test****************



");
} 

6) impalement "- (IBAction)ClickOnLineImageTest:(id)sender" method as following

- (IBAction)ClickOnLineImageTest:(id)sender {
     NSLog(@"*************Test Online Image****************
");
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 
",[UIImageJPEGRepresentation(img, 1.0) length]/1024);
NSLog(@"*************Completed test****************



");
}

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...