2013/06/04更新

[フロント] JPG,GIF,PNGの違いを比較&それぞれのファイルフォーマットについて詳しく調べてみた

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
今日は、Webでよく使う画像フォーマットのJPGとGIFとPNGですが、その違いを良く理解していない部分もあったので、 改めてそれぞれの画像フォーマットに関する情報を纏めてみました。

画像


Webでよく使う画像フォーマット

Webページを制作する上で、写真やイラストなどを表示するために画像を表示することが多いと思います。
その際に、写真はJPG、小さなアイコンはGIF、グラフィックはPNGが良いなど、色々と情報は持っているのですが、 それがどういう理由なのかを正確には理解できておらず。。今回はそれら画像フォーマットの違いについてブログに記載したいと思います。

今回の記事の目次は以下の通りです。
  1. 各画像フォーマットのまとめ
  2. JPGとは
  3. GIFとは
  4. PNGとは
  5. 最後に



1、各画像フォーマットまとめ

まずはこのブログで扱う画像フォーマット3つについて、表形式で纏めてみました。
同じ軸で違う画像フォーマットを比較することで、それぞれの特徴が浮き上がります。 (以下の表形式に記載した内容は、Webで利用することを想定して記載しています。そのため、多くのブラウザがサポートしていない形式(例:PNG48bit)などは記載を省いています)。

  JPG GIF PNG
圧縮形式 非可逆圧縮(画像劣化する) 可逆圧縮 可逆圧縮
色数 約1678万色(24bit) 256色(8bit) 約1678万色(24bit)
透過 透過不可 透過可能(1色) 透過可能(1色,半透過)
アニメーション 不可 可能 不可

以下の記事では、それぞれの画像フォーマット毎に詳しく内容を記載したいと思います。



JPG


非可逆圧縮について

JGPは、他の画像フォーマットと異なり非可逆圧縮であるという点が、大きな違いです。
非可逆圧縮とは、「圧縮した物から表示した画像は、圧縮前の画像とは異なる」という圧縮フォーマットです。1回圧縮しちゃうと、まったく同じものは復元できないよー、という圧縮形式なのです。

「同じ物を復元できないなら使えないんじゃん?」と感じるかもしれませんが、それは使いどころによっては使えるのです。
JPG形式が良く利用される画像として写真(デジカメなどで撮影した場合は特に)が挙げられます。写真は撮影物によりけりですが、多くの場合、色の変化が多様です。例えば風景を撮影した場合、1枚の写真の中に緑や青色や色々な色が入っていたり、同じ緑でも彩度や明度が異なり多くの種類の緑が入っています。
このような画像を非可逆圧縮した場合に、圧縮前後で画像の内容が完全一致はしないですが、人の目にはその違いが分かりません(色数や色変化が多様なため、どこが画像劣化しているのか気づけません)。
というように、非可逆圧縮のフォーマットも、使いどころがあるのです。
PNGやGIFといった可逆圧縮を使わずに非可逆圧縮を使う理由として、たくさんの色数(24bit)を使った画像でも、良い効率で圧縮できるというめりっとがあります。

以上のことから、色数が多く色変化が多い画像は、JPG形式での圧縮をしても、画像劣化していることに気づきづらく、サイズも抑えられると言えます。


圧縮アルゴリズム

なぜJPGは非可逆圧縮なのか。この疑問を紐解くために、圧縮アルゴリズムを見て行きましょうー!
JPEGの圧縮は、Wikipedia:JPEGによると以下の手順で行われるとのことです。

1、8×8画素を1ブロックとしてサンプリング。
   ↓
2、離散コサイン変換を行い、離散値から周波数領域へ変換。
   ↓
3、2の変換結果に対して量子化を行い、大雑把に値の区間を分ける。
   ↓
4、エントロピー符号化を用いて、圧縮を行う。

という流れです。難しいですね。。
ポイントとしては、「3」の部分です。量子化を行うことで、データの種類を適度に間引くことが、非可逆圧縮となっていると思われます。
「1→4」や「1→2→4」の手順でもRowデータ(圧縮前のデータ)からはサイズ圧縮できますが、「3」を行うことでより圧縮率を上げているのかなぁと。
画像圧縮は、ランレングス形式、エントロピー形式など色々あって難しいです。これから勉強して行きたい分野です。


圧縮率について

PhotoshopなどでJPGファイルとして保存する際に、圧縮率を指定することが出来ます(市販のデジカメだと、ファイン、普通、など)。
圧縮率を上げることでファイルサイズを削減できる反面、画像が粗くなってしまいます。
圧縮率は、上記アルゴリズムの中の「量子化」の部分で利用されます。圧縮率を高くするとより多くのデータを間引くことになります。

圧縮率別に、以下のような違いが発生します。

■高画質(クオリティ=100)
画像

■中画質(クオリティ=30)
画像

■低画質(クオリティ=10)
画像

■超低画質(クオリティ=2)
画像


低画質になるにつれて、汚くなっちゃいますね。。画像のクオリティとファイルサイズのバランスを考慮して、圧縮率を考える必要がありそうです。


モスキートーノイズ

JPEGでは、モスキートーノイズという特徴的な表示不備が表示されることがあります。
モスキートーノイズは、特にアイコンやイラストなどのパキッとした感じの画像(境界がはっきりした画像)で表示されます。以下がモスキートーノイズのサンプルです。
画像

文字の周りになんだかガビっとしたノイズが入ってるやつです!汚く感じてしまいます。
これはJPEGの圧縮アルゴリズムの特性からくるノイズのようです。
こーゆう画像はJPGではなく、後述のGIFやPNGを画像形式として用いるべきです。


ブロックノイズ

圧縮率を高くすると、ブロックノイズという表示不備が表示されます。
これは圧縮アルゴリズムで「8×8」サイズごとに圧縮を行うという部分が起因していて、それぞれブロック毎に再現できる表示が異なってしまい、その結果、お隣さんのブロックと違った見え方になってしまいます。
ブロックノイズが強いとモザイク状に見える感じです。以下がサンプルになります。
画像

上記は、超低画質なのでブロックがはっきりと見えています。描画内容によりブロックノイズが目立つ場合と目立たない場合もありますので、色々と圧縮率は調整する必要があります。


参考資料

JPGの記事を記載するために、以下サイトを参考にさせて頂きました。
ありがとうございます☆
- JPEG画像形式の概要(圧縮アルゴリズム) - ウェブで用いられる画像形式。
- (連載)第2回:JPEG(じぇいぺぐ)
- 量子化行列のナゾ~その1


Topへ戻る▲

GIFについて

次はGIFのお話です。


圧縮アルゴリズム

GIFのアルゴリズムは、LZWというアルゴリズムを採用しています。LZWはデータの横の並びに注目して、「同じようなデータが並んでいたらそれを短縮する」という圧縮です(かなり説明が雑w)。詳細は、「GIFフォーマット講座1:画像データの圧縮(LZWについて)」の記事が分かりやすかったので、そちらをご参照ください。
またGIFは、その昔はライセンス問題というものがあったようですが、現在は解消されています。特許問題については、「Wikipedia」をご参照ください。


透明色の指定について

GIFは、透明色を指定することができます(半透明は無理です)。ファイル構造的には、ヘッダ部分で「Transparent Color Flag」をONにして、「Transparent Color Index」にカラーテーブルのどの色を透過色と認識するかを指定します。
ファイル仕様はそんな感じなのですが、GIFを作るのはPhotoshopとかGIMP2とかツールを使うかと思いますので、特にファイル形式は意識する必要はないと思います。
ポイントとしては、GIFは、透過色を1色指定出来て、半透過は指定出来ないという点です!
1色しか指定出来ないので、丸みの部分のアンチエイリアスが綺麗に表現出来なかったり、グラデーションでマスクをかけた画像が綺麗に表現されなかったりと、「ジャギる」ことがあります。


アニメーションGIFについて

画像形式にGIFを選択する一番のポイントは、アニメーションGIFというものが使えるという点ではないでしょうか。 アニメーションGIFは、以下のようなコマアニメーションを行う仕組みです。

画像
上記画像は、以下のように複数枚の画像から成り立っています(以下はPhotoshopのレイヤー例)。
画像

上記のアニメーションを行うファイルですが、ファイルとしては1つのGIFファイルとして保存することが出来ます。
ファイルの中身の構造としては、以下のようにそれぞれの画像を保持するような作りです。
画像(アニGIFの構造例) 上記の構造で分かる通り、コマ毎に情報を保持しているので、コマ数を多くするとアニメーションは滑らかになりますが、ファイルサイズは増大してしまいます。
アニメーションは、ループ数(1〜65535)とフレームレートを指定することが出来ます。ただし、再生速度はブラウザによりだいぶ異なるので、このブラウザだと早いけど、こっちだと遅いなぁという現象が発生してしまいます。。

ただ、アニメーションはJPGでもPNGでも出来ない機能で、GIF以外でアニメーションを行う場合にはFlashやJavaScriptやらを実装する必要があるので、手軽にアニメーションをさせたい場合には、GIFアニメーションは便利です。


参考資料

GIFに関して参照したサイトは以下です。より詳細な説明があるなど有益な情報が多いです。
- GIFフォーマットの詳細 | とほほ
- GIFフォーマット講座1:画像データの圧縮(LZWについて)
- Wikipedia:GIF(英語)
- GIF89a Specification(英語)


Topへ戻る▲

PNGについて

続いてPNGのお話です。


PNGの種類

PNGには大きく分けて以下の3つの種類が有ります。

1、グレースケール

グレースケール画像を扱う形式

2、インデックスカラー

256色と限定された色数を扱い、後述のトゥルーカラーよりも圧縮効率が良い形式

3、トゥルーカラー

24bitカラー(もしくはそれ以上)の色数を扱える形式


上記のうちWeb用に使うのは、インデックスカラーとトゥルーカラーかと思いますので、それらについて記載したいと思います。



インデックスカラー

画像
インデックスカラー形式とは、色数を256色に限定することで圧縮効率を上げるPNGの形式です(256色PNGとか、PNG8とか呼ばれます)。
インデックスカラー形式ではPNGデータ内にカラーテーブルと呼ばれるものを持っていて、そのテーブルに最大256色を指定することが出来ます。指定する色は好きに決めることが出来ます。
(PhotoshopでWeb用に保存の時とかに出てくるカラーテーブル例)
画像

データ部分は、カラーテーブルのどの値を使うかを指定する情報のみを持っています。後述のトゥルーカラーでは、1ピクセル毎にRGBの各8bitの計24bitを保持していますが、カラーテーブルの値の指定は256パターン(=2の8乗)で指定できるため、1ピクセルにつき8bitで表現でき、トゥルーカラーの1/3程度の情報量でデータを保持できます。


またカラーテーブルに登録されたそれぞれのカラーについて透明度を指定することが出来ます。 Photoshopで書き出したPNG8は、透明は「透明か否か」の0 or 1での指定しか出来ませんが、本当はカラーテーブル上の各色ごとに256段階で透明度を指定でき、半透過も指定することが可能です(Web上の情報ではFireworksではPNG8で半透過画像も書き出せるらしいですが、試していません)。

ただデザインでよく使われるPhotoshopやIllustoratorでのPNG8の書き出しでは半透過を行うことが出来ないため、インデックスカラー形式は半透過が出来ない形式と考えられているし、考えてもいいかなぁと思います。


トゥルーカラー

画像

トゥルーカラーは、インデックスカラー形式と異なりカラーテーブルは持たず、各ピクセルごとにRGBの値を保持するデータ形式です。 カラーテーブルの256色という限定がないいため、24bitカラー(またはそれ以上)の色数を使うことができ、表現豊かな画像を正確に表示することが可能です。
しかし一方で、各ピクセル毎にRGBの色情報を保持するため、ファイルサイズが大きくなるという点が欠点となります。

トゥルーカラーでは、アルファチャネルと呼ばれる透明/半透明を各ピクセルごとに表現することが出来ます。インデックスカラー形式では色毎に透明度を指定しますが、トゥルーカラー形式ではピクセルごとに透明度を指定することが可能なため、ドロップシャドウやアンチエイリアスのかかった曲線を綺麗に表現することが出来ます。


減色について

PNGを扱う際に良く話題に上がるのが「減色」という作業(処理)です。減色を行ってファイルサイズをなんとか減らそうというお話です。
減色で最も効果が高い作業内容は「トゥルーカラー形式からインデックス形式」へ変換することです。 トゥルーカラー形式では24it/ピクセルの情報量が必要なところを、インデックスカラー形式では8bit/ピクセルの情報量になるため、おおよそサイズが1/3になります(ただしカラーテーブルの情報が増えるなど、完全に1/3になる訳ではありません)。

トゥルーカラー形式からインデックスカラー形式へ変換する際に注意するポイントは以下の点です。

1、色の変換
24ビットカラーから8ビットカラーに色数を落とすため、どのように色を減らすか。これは減色アルゴリズムで何を選択するかで変換後の色が決まります。

2、アルファチャネルの扱い
トゥルーカラーでアルファチャネルがあるピクセルについては、変換後にアルファチャネルがなくなってしまうので、変換後に画像の中の透明な部分を注意して見て、場合によってはレタッチする必要があります。

ということでこんな感じで減色作業をすることで、PNGのファイルサイズを削減することができます。


圧縮アルゴリズム

PNGの圧縮処理は、以下の手順で行われます。

1、データ部分の情報にフィルター処理を掛けて、後続の処理でより圧縮効率が上がるようにデータ整形を行う
2、Deflateという圧縮アルゴリズムを提供する

アルゴリズムの詳細は、「PNG軽量化の減色と圧縮について - Gree Engineer's Blog」の記事が分かりやすかったので、そちらを参照頂けると幸いです。

PNGの画像最適化ツールが多く出回っていますが、それらツールでは「フィルター処理」や「Deflate」をより最適に行うことで圧縮効率を上げているようです(あとヘッダ部分にあるメタ情報削除もしてファイルサイズを削減します)。


インデックスカラー形式で色数を256色から128色や32色に減らすと圧縮効率が上がる?

はい、上がります。これは上述の圧縮アルゴリズムが関係するようです。圧縮アルゴリズムで使われているLZSSとハフマン符号化では、頻出する単語の割合が全体の中で多ければ多いほど、より高い圧縮効率となります。
そのためアイコンやイラストなどで可能であれば、色数を制限することで高圧縮のPNGファイルを生成することが可能です。


参考資料

- W3C PNG Specification
- 分かりやすいPNGの話 for Web
- PNG軽量化の減色と圧縮について - Gree Engineer's Blog


Topへ戻る▲

最後に

なんとなく使い分けていた画像のファイルフォーマット。 色々と調べてみるとそれぞれの違いが分かって、より確かな使い分けが出来そうな気がしてきます。
プログラムを書いている身としては、アルゴリズムにもすごく興味を惹かれました。かなり難しそうだったのですが(特にJPG)、少しずつ理解してよりハイレベルなプログラマになれるように頑張りたいと思う今日この頃です。

ほんとは、各画像ファイルのシチュエーション別の使い分けも書きたかったのですが、だいぶ記事が長くなったので次回以降に書きたいと思います。
最後までご覧頂きましてありがとうございました。





こんな記事もいかがですか?

[セミナー] Frontrendというセミナーに参加してきました(フロント開発のフレームワークやツール編)
[Tool] フロント開発で重宝するSublime Text2の便利と感じるショートカット21個
[取り組み] フロントエンドでコーディングスピードをアップさせる6つの方法!と思って書いてたら30個も書いちゃった。
[フロント] JPG,GIF,PNGの違いを比較&それぞれのファイルフォーマットについて詳しく調べてみた
[フロントエンド] フロントエンドの入社試験99問!難しいですよ〜w。
[フロントエンド] Webページを表示するテストの際に、通信速度を3Gに制限して表示してみよう
[フロントエンド] スマホ実機でのデバッグ手段を増やす!Macのプロキシを利用して、通信内容を確認する。
RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。