なぜ iPhone の画像は Android の画像よりもずっと高品質なのか

  • 776
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

原文は「 https://github.com/bither/bither-android-lib/blob/master/REASON.md


なぜ iPhone の画像は Android の画像よりもずっと高品質なのか

Android と iPhone との比較は多くの点で議論されており、どちらがより良いかは、Android の画像の質は iPhone とくらべてずっと劣るという点を除けば、未だ結論が出ていません。Facebook、Twitter、Instagram 等どれを使っていても、写真をとって、フィルタをかけて、ソーシャルネットワーク上に公開すると、いつも Android から投稿される写真は画質が劣化しています。しかし何故でしょう?

私達は昨年の間調査をし、そしてついに、Google が犯したほんのちょっとしたミスが原因であることを突き止めました。それは本当にちょっとしたミスでしたが、その影響はすべての画像を扱うアプリケーションに波及するほど大きく、現在に亘っても影響が続いています。

問題は、libjpegです。

libjpegといえば、数多くのオープンソースプロダクトでも使用されており、Android も画像の圧縮に使っています。Android のソースコードを見ると、Android では、libjpegを直接使用せず、Skiaという画像処理エンジンをベースに使用していることがわかります。Skiaは Google がメンテナンスをしているエンジンで、必要な機能はすべて実装されており、Google や他の多くのプロダクト(Chrome、Firefox、Android など)で広く使われています。Skiaはうまくlibjpegをカプセル化しており、だれでも簡単に画像処理ライブラリを作ることが出来るようになっています。

libjpegを使って圧縮を行うとき、非常に重要なoptimize_codingというパラメータがあります。ドキュメントによると、このパラメータについて以下のような説明があります。


boolean optimize_coding
    TRUE causes the compressor to compute optimal Huffman coding tables
    for the image.  This requires an extra pass over the data and
    therefore costs a good deal of space and time.  The default is
    FALSE, which tells the compressor to use the supplied or default
    Huffman tables.  In most cases optimal tables save only a few percent
    of file size compared to the default tables.  Note that when this is
    TRUE, you need not supply Huffman tables at all, and any you do
    supply will be overwritten.

optimize_codingTRUEに設定すると、より多くのディスクスペースと時間を要するために、デフォルト値はFALSEとされていることがわかります。

ドキュメントも普通ですし、libjpegも安定していることから、何も問題はなさそうに見えます。しかし、このドキュメントが 10 年以上前に書かれた、ということにもっと注目すべきです。その頃は、メモリも計算能力もとても限られていました。しかし、今日のコンピュータやスマートフォンが持っている計算能力を鑑みると、これはもはや問題ではなくなりました。その代わりに、私達は画質と画像サイズについてより注目していくべきなのです。

Google のSkiaを担当しているエンジニアは、このパラメータを設定しませんでした。つまり、Skialibjpegoptimize_codingFALSEのままです。そしてSkiaはこのパラメータを完全にライブラリに隠蔽してしまったため、Skiaの外からこのパラメータを設定することすらも出来ません。このことが大きな問題となり、私達は大きなファイルサイズと劣化した画像を強いられています。

私達はoptimize_codingを様々な画像でテストしました。圧縮後の画質を同じにしようとしたとき、optimize_codingTRUEにした時に比べて、FALSEにした時のファイルサイズは 5〜10 倍に膨れ上がりました。この違いはとても大きなものです。

私達はまた、iOS と Android での Jpeg 圧縮の差異についても検証しました。同じ原画像に対し、おなじ画質レベルを保つ場合、Android のほうが 5〜10 倍のファイルサイズを必要とします。

結果は明らかです。Apple はoptimize_codingHuffman tablesについての重要性を良く知っており、Google はそうではなかったということです(Apple は独自の Huffman table アルゴリズムを使っており、画像圧縮についてより多くのチューニングをしているようです)。

最終的に、私達は Android の提供する画像圧縮機能を使わないことにしました。その代わりに、自分たちでビルドしたlibjpeg-turboをベースとしたライブラリを使うことにしました(libjpeg-turbo もパフォーマンスが改善されています)。これによって、私達はこれまでより 5〜10 倍スペースを確保し、同じかよりよい画質を得ることができました。これは誰もがすべきことだと思います。


という訳で、Android の libjpeg が何故腐っていると言われ続けているのかが良くわかる記事の紹介でした。