14

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

重现步骤:

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

2) 打开 ViewController.xib 并添加两个按钮,名为 i)Test Online Image ii)Test Local image

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

7)现在在Xcode 4.0以后和IOS3.0以上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******************

我的问题 :

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

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

4

1 回答 1

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 以获得与上述数字的正确比率)。

于 2013-01-19T05:56:42.737 回答