iOSアプリケーションのリソースの最適化

iOS用のアプリケーションを構築する場合、Xcodeスイートのiphoneos-optimizeスクリプトを使用してリソースを最適化します。 うまく機能しますが、少し深く掘り下げると、圧縮されていないファイルもあれば、わずかに縮小されているものの、まだ理想から遠いファイルもあることが明らかになります。 スクリプトのタスクは、ファイルをiPhoneとより互換性のあるものにすることであるため、ファイルの読み取りや解凍を高速化することができますが、おそらく古いiPhone 1などでのみ意味があり、すでにARM 7を搭載した1 GHzプロセッサでは意味がありません。

簡単な最適化とMacPortsスイートのいくつかのプログラムの助けを借りて、最終プログラムおよび必要に応じて他の種類のデータのPNGおよびJPG画像を大幅に削減できます。



知能


最初に、元のiphoneos-optimizeが何であるかを見てみましょう。 これは小さなPerlスクリプトで、/ Developer / Platforms / iPhoneOS.platform / Developer / usr / bin /フォルダーにあります。 Xcode 4.3以上の場合、これは/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/フォルダーになります



スクリプトの主要部分は非常にシンプルで読みやすいものです。

print "$SCRIPT_NAME: Converting plists to binary in $dstroot\n"; find( { wanted => \&optimizePlists }, $dstroot ); exit(0) if defined $options and $options =~ /-skip-PNGs/; print "$SCRIPT_NAME: Optimizing PNGs in $dstroot\n"; find( { wanted => \&optimizePNGs }, $dstroot );
      
      







ここでは、dstroot内のすべてのファイルがソートされ、optimizePlistsおよびOptimizePNGs関数への入力に送信されます。 PNGの最適化のために、Appleはiphoneキーで修正されたpngcrunchバージョンを使用します。



 my @args = ( $PNGCRUSH, "-iphone", "-f", "0", $name, $crushedname ); if (system(@args) != 0) { print STDERR "$SCRIPT_NAME: Unable to convert $name to an optimized png!\n"; return; } unlink $name or die "Unable to delete original file: $name"; rename($crushedname, $name) or die "Unable to rename $crushedname to $name";
      
      







Pngcrush対OptiPNG


-iphoneキーは正確には何を知りませんが、概してそれはそれほど重要ではありません。 詳細な調査によると、pngcrushがエラーを返した場合、またはファイルを縮小できなかった場合、一時ファイルは削除され、メインファイルは変更されません。 私の場合、これは特定のbrowser.pngファイルで発生しました。



Recompressing browser.png

Total length of data found in IDAT chunks = 433949

IDAT length with method 120 (fm 1 zl 9 zs 1) = 512501

Best pngcrush method = 120 (fm 1 zl 9 zs 1) for browser_iphone.png

(18.10% IDAT increase)

(18.11% filesize increase)




CPU time used = 2.569 seconds (decoding 0.040,

encoding 2.490, other 0.039 seconds)








-iphoneスイッチがなければ、状況は良くなり、ファイルはさらに小さくなりました。



Recompressing browser.png

Total length of data found in IDAT chunks = 433949

IDAT length with method 1 (fm 0 zl 4 zs 0) = 740769

IDAT length with method 2 (fm 1 zl 4 zs 0) = 611778

IDAT length with method 3 (fm 5 zl 4 zs 1) = 485419

IDAT length with method 9 (fm 5 zl 2 zs 2) = 743935

IDAT length with method 10 (fm 5 zl 9 zs 1) = 427514

Best pngcrush method = 10 (fm 5 zl 9 zs 1) for browser_tmp.png

(1.48% IDAT reduction)

(1.47% filesize reduction)




CPU time used = 3.949 seconds (decoding 0.176,

encoding 3.766, other 0.007 seconds)








しかし、別の方法もあります-GPLユーティリティoptipng 。 MacPortsから、コマンドでシームレスにインストールします

sudo port install optipng







同じbrowser.pngを使用したユーティリティの結果は次のとおりです。

** Processing: browser_opti.png

1024x1024 pixels, 4x8 bits/pixel, RGB+alpha

Input IDAT size = 433949 bytes

Input file size = 434043 bytes



Trying:

zc = 9 zm = 8 zs = 1 f = 5 IDAT size = 427390



Selecting parameters:

zc = 9 zm = 8 zs = 1 f = 5 IDAT size = 427390



Output IDAT size = 427390 bytes (6559 bytes decrease)

Output file size = 427484 bytes (6559 bytes = 1.51% decrease)








ご覧のとおり、ファイルサイズはpngcrushのサイズよりもさらに小さくなり、作業の速度は著しく速くなっています。 他のいくつかのケースでは、ギャップはさらに顕著です。

最も重要なことは、生成されたPNGファイルはiPhoneとiPadで完全に開き、それらに視覚的な歪みはなく、開く速度の違いが存在しないか、目立たないことです。



optipngをスクリプトに統合するのは非常に簡単です。スクリプトのヘッダーで、変数をPNGオプティマイザーとそのパスで変更します。

 my $PNGCRUSH_NAME = "optipng"; my $PNGCRUSH = "/opt/local/bin/$PNGCRUSH_NAME";
      
      





optimizePNGs関数本体では、パラメーター文字列のみが変更されます。 -o2および-f0オプションを使用すると、最高の結果が得られました。

 my @args = ( $PNGCRUSH, "-o2", "-f0", $name, "-out", $crushedname );
      
      







もちろん、スクリプトをバックアップすることを忘れてはなりませんが、同時に編集する管理者権限が必要です。



JPG最適化


JPEGファイルには多くの場合EXIF情報が含まれており、電話では不要なさまざまなゴミが含まれることもあります。 プログレッシブモードと他の設定を使用する場合にも違いがあります。 jpegoptimユーティリティを使用すると最も便利です。このユーティリティ自体は、不要なものを破棄し、ハフマンテーブルを最適化し、同じ品質レベルで最適な設定を選択します。 必要に応じて、ユーティリティが画像品質を下げるようにパラメータを設定できます。その後、指定された品質で再び圧縮されます。 MacPortsからインストールすることもできます。



sudo port install jpegoptim







iphoneos-optimizeでこのプログラムへの呼び出しを追加するだけです。

タイトルに:

 my $JPGCRUSH_NAME = "jpegoptim"; my $JPGCRUSH = "/opt/local/bin/$JPGCRUSH_NAME";
      
      





本体内:

 print "$SCRIPT_NAME: Optimizing jpgs in $dstroot\n"; find( { wanted => \&optimizeJPGs }, $dstroot );
      
      





新機能:

 sub optimizeJPGs { my $name = $File::Find::name; if ( -f $name && $name =~ /^(.*)\.jpg$/i) { my @args = ( $JPGCRUSH, "--strip-all", $name ); if (system(@args) != 0) { print STDERR "$SCRIPT_NAME: Unable to convert $name to an optimized jpg!\n"; return; } print "$SCRIPT_NAME: Optimized JPG: $name\n"; } }
      
      





最適化が失敗した場合、ソースファイルが変更されないため、プログラムの結果を意図的に繰り返しません。

このユーティリティは非常に高速に動作し、最小限の情報を表示します。



jpegoptim --strip-all english.jpg

english.jpg 320x480 24bit JFIF [OK] 66466 --> 59686 bytes (10.20%), optimized.








Xcodeでプロジェクトを再構築するだけで十分です。iphoneos-optimizeを使用してリソースを最適化するプロセスははるかに高速になり、結果は10〜15%少なくなります。



その他の最適化


さらに、スクリプトに他の拡張機能(JPEG、JFIF、JPE、JIFなど)を追加したり、品質の低下などを追加したりすることもできます。とにかく、使用できるネットワーク上には非常に多くの異なるPNG、JPEG、CAFオプティマイザーなどのファイルがあります。 たとえば、SQLiteデータベースは次のコマンドで最適化できます。

sqlite3 database.sqlite vacuum;







チームは、すべてのデータを使用してデータベースを再作成し、さまざまなゴミ、古いトランザクションの残りなどを捨てます。 スクリプトでのこのコマンドと他のコマンドの統合は、読者次第です。



実際、PNGファイルのサイズを小さくするには、さらに2つ以上の興味深い方法があります(他のオプティマイザープログラムを捨てて、手動で画像を単純化する場合)。 1つ目は完全に標準的なものではなく、異端と見なすことができますが、事実があります。Androidコンパイラー(より正確にはapktool)は少数の色で画像を追跡し、パレット形式に変換できます。 さらに、フルカラーのPNGでさえ、さらに小さくなります。 作業中のプロジェクトのres / drawableフォルダーに必要な画像を追加し、それを収集して、bin / res / drawableフォルダーから最適化されたファイルを削除するだけで十分です。 もちろん、これにはAndroid SDKのスキルが必要であり、iOSの開発にはまったく適用されません。



2番目の方法はより一般的です。ファイルの色域をRGBA8888からRGB565またはRGBA4444に減らします。 同時に、ディザリングのためにサイズが大きくなり、描画された画像の場合はサイズが大幅に小さくなります。 これらの操作のために、私は独自のコンソールユーティリティを作成しましたが、その検討はすでにこの記事の範囲外です。



完成したiphoneos-optimizeスクリプトのPSテキスト: paste2.org/p/2045147




All Articles