当我使用UIImagePNGRepresentation或UIImageJPEGRepresentation将UIImage转换为NSdata时,图像大小增加太多

时间:2013-01-19 05:20:04

标签: ios

当我使用UIImagePNGRepresentation或UIImageJPEGRepresentation将UIImage转换为NSdata时,图像尺寸会大幅增加。

重现步骤:

1)打开Xcode并选择新项目作为基于单一视图的应用程序

2)打开ViewController.xib并添加两个名为i)的按钮测试在线图像ii)测试本地图像

3)添加两个IBAction

  i)  -(IBAction)ClickLocalImageTest:(id)sender;

  ii) -(IBAction)ClickOnLineImageTest:(id)sender;

4)将“测试在线图像”连接到“-(IBAction)ClickOnLineImageTest:(id)sender

和“测试本地图片”到“-(IBAction)ClickLocalImageTest:(id)sender;”

5)刺穿“-(IBAction)ClickLocalImageTest:(id)sender”方法,如下所示

- (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)刺穿“- (IBAction)ClickOnLineImageTest:(id)sender”方法如下

- (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)请从here下载“hero_ipad_retina.jpg”图片并保存在名为“hero_ipad_retina.jpg”的资源中

7)现在在Xcode 4.0上运行此项目,在SDK上面运行IOS3.0

**

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******************

我的问题:

为什么它会增加它的大小?什么是将图像转换为NSData的优化方法?

注意: 请从here下载“hero_ipad_retina.jpg”图片并保存在您的资源中

1 个答案:

答案 0 :(得分:9)

“hero_ipad_retina.jpg”是压缩的jpg图像

这一行:

[[NSData dataWithContentsOfFile:path] length]/1024

给出了压缩文件的大小......

这一行:

[UIImagePNGRepresentation(img) length]/1024

解压缩图像并将其转换为PNG,这是一种无损文件格式。它的大小不可避免地要大得多。

这一行:

[UIImageJPEGRepresentation(img, 1.0) length]/1024  

解压缩图像,将其重新压缩为JPG表示。您已将质量设置为最大值(1.0),因此 - 与原始版本相比,无疑会将其压缩到较低的质量 - 您可以获得更大的文件大小。如果将质量设置为0.5,则会得到一个小文件大小(大约42K)

这是一个很好的提醒,为什么你应该谨慎对待jpeg图像。每次访问jpeg imageRep时,都会解压缩。如果你再重新压缩 - 即使是全质量 - 你正在降低图像的质量(因为每个有损压缩都比前一个更差)。随着图形图像(平面颜色,直线/对比边缘),人工制品增加并变得特别明显。 PNG总是更安全 - 它在24位时无损,在8位时非常适合处理平面颜色的区域。

<强>更新

获取内存中图像的大小:

NSUInteger sizeInBytes  = 
  CGImageGetHeight(image.CGImage) * CGImageGetBytesPerRow(image.CGImage);

由此可以计算出PNG,JPG和原始文件的压缩率(除以1024表示千字节,以获得与上述数字相符的正确比率)。