14

UIImage を NSdata に変換するために UIImagePNGRepresentation または UIImageJPEGRepresentation を使用すると、画像サイズが大きくなりすぎます。

再現する手順:

1) Xcode を開き、新しいプロジェクトをシングル ビュー ベースのアプリケーションとして選択します。

2)ViewController.xib を開き、i)Test Online Image ii)Test Local image という名前の 2 つのボタンを追加します。

3) 2 つの IBAction を追加する

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

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

4)「Test Online Image」を「-(IBAction)ClickOnLineImageTest:(id)sender」に接続

および「Test Local image」を「 -(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 以降および 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 に変換する最適な方法は何ですか?

注:ここから「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 に答える