PNG画像形式について解説します。
PNG(ピング)とは「ポータブル・ネットワーク・グラフィックス」の略で、GIF画像の基幹技術であるLZW圧縮アルゴリズムに特許問題が絡んだために、GIF画像及び同様にLZW圧縮を利用しているTIFF画像形式(ウェブでは使われないが、印刷用などオフライン向けの画像ではよく利用されている)を置き換えるためのパテントフリー(特許無問題)の規格として、西暦1996年(平成 8年)に策定されました。
PNG画像形式の主な特徴は以下の通りです。
GIF画像同様かなり小さく圧縮させる事が出来、圧縮されたデータは元通りに展開される可逆圧縮となります。
透過のみならず、半透明も可能です。特にフルカラー及びグレイスケールではアルファチャネルと呼ばれる、ピクセルごとに透明度を指定する機能も利用出来ます。
また、インデックスドカラーでもパレットごとに透過度が指定出来ます。
後発の技術のため、サポートが遅れておりました。特に携帯電話ではシェアが圧倒的なiモード端末は今もってサポートしていないため、かなり不利な状況にあります。
複数の画像を一本のファイルに纏める事は出来ません。この結果、アニメーションは不可能となり、これがPNG画像の普及を遅らせた最大の理由となりました。
PNG画像は策定されて以来、ISOなどの国際規格にもなっておりますが、現実には当初の目論見通りにGIF画像を駆逐する事が出来ないままLZW圧縮アルゴリズムの特許権失効を許してしまい、現在でもGIF画像の牙城を崩せないでいるのが実情です。ざまあ見ろ!!!!!!
PNG画像ファイルは、シグネーチャと呼ばれるヘッダ部と、幾つかのチャンクと呼ばれるブロックから成ります。
シグネーチャとは、直訳すると「署名」と言う意味で、PNG画像ファイルの先頭に付くストリングです。
具体的には、以下のような構成になります。
画像処理ソフトウェアは、このシグネーチャを確認してPNG画像と判断します。
PNG画像以外でもシグネーチャに相当するデータは必ずファイルの先頭に入れられており、それらは形式によって異なるため、画像処理ソフトはそれぞれの特徴に合致するかを調べた上で適切なフォーマットの処理を行います。
チャンクとは直訳すると「塊」と言う意味で、PNG画像ではデータブロックの事を指します。
チャンクには機能に応じて英字四文字の名前が与えられます。
チャンクの形式は常に一定で、先頭から順に以下のような構成となります。
チャンクの機能に応じて与えられた英字四文字の名前です。
名前の大文字小文字にはそれぞれに意味があります。
CRCとは、チャンク名と本体データが正常に書かれているかを確認するチェックディジットの事です。
CRCの算出法は仕様書で紹介されております。
PNG画像ファイルを作成するに当たって、以下の約束事があります。
PNG画像には幾つものチャンクが仕様書で定義され、また仕様書に無い機能を持たせた私的なチャンクを定義する事も出来ます。
このうち、PNG画像における主要なチャンクは以下の通りです。
IHDRチャンクはPNG画像シグネーチャの直後に現れるべき必須チャンクです。
画像の大きさ、色深度(ピクセルを表現するのに必要なビット数)、カラー/白黒の区別、圧縮形式、フィルタ形式などが収められております。
具体的には以下の順にデータが収められます。
1ピクセルを表現するのに必要なビット数を入れます。
値は 8または 8の倍数か約数となります。
カラーか白黒(グレイスケール)の区別、アルファチャネルの有無を入れるものです。
以下の値を加算したものとなります。
圧縮方法を指定します。
但し、現行の仕様では 0(デフレート圧縮(LZ77圧縮))以外は定義されていません。
フィルタの方式を指定します。
但し、現行の仕様では 0以外は定義されていません。
PLTEチャンクはパレットデータを収めた必須チャンクです。
後述のIDATチャンクより前に現れていなければなりません。
実際の構成は、一パレットコードはR(赤),G(緑),B(青)の 3オクテットとなり、パレットコード 0番から順にこの形式のデータが並びます。
データの数は、実際に画像で利用されているパレットコードが全部定義される範囲で良い事になっております。
例えば、色深度が 8ビットなら最大256色が使えますが、実際にはパレットコードが17番までしか使われていない場合は 0番から17番までの18組54オクテットのデータを用意すれば良い事になります。
tRNSチャンクは透過に関する情報を与えますが、インデックスドカラーと他の形式では扱いが異なります。
tRNSチャンクを用いる場合はIDATチャンクの前に、特にPLTEチャンクがある場合はPLTEチャンクとIDATチャンクの間に、設置しなければなりません。
インデックスドカラーでのtRNSチャンクはパレット毎の透明度を指定するチャンクです。
PNGの最大の特徴となっているアルファチャネルは全ピクセルにそれぞれ指定する必要があり、当然画像データを肥大化させる事になります。
特定のパレットコードに特定の透明度を設定したい場合(GIFの透過機能に対応する機能を実現する場合など)は、アルファチャネルの代りにtRNSチャンクで透明度を指定する方が効率がいいと言う事になります。
各パレットコートに対して、 1オクテットのデータが与えられます。データは0にすると完全透明、255だと不透明となります。
尚、実際に利用しているパレットコードの数より少ないデータでも構わない事になっており、その場合対応するデータの無いパレットコードは255(不透明)と見做します。
グレイスケール及びフルカラーでの場合、tRNSチャンクは透明色を一色だけ指定します。
透過扱いとなるピクセル値を定義するだけです。
IDATチャンクは画像データを表すチャンクです。
画像ソフトや圧縮ルーティンの都合により、複数のIDATチャンクに分割しても構わない事になっておりますが、その場合分割されたIDATチャンクは必ず連続させなければなりません。
また、複数のIDATチャンクに分割する場合、どのような分割をしても構わない事となっております。
実際のデータは、IHDRチャンクで指定した圧縮方式で圧縮された画像データとなります。
IENDチャンクはPNG画像データの終端を表すチャンクで、必ずPNG画像ファイルの一番最後に出現していなければなりません。
本体データは空となります。
この他、PNG画像ではgAMAチャンク(ガンマ値…色調の強さ)や、pHYs(ピクセルの縦横比または 1メータ当たりのピクセル数)なども定義されておりますが、対応していないソフトウェア(作成ソフトもブラウザも含む)も多いようです。
加えて、tEXtチャンク(欧米語のテキスト文字列)を用いて文字列を埋め込む事も出来ます(但し、tEXtチャンクはISO-8859-1以外の文字セットは使えないので日本語文字は使えません)。
また、二文字目を小文字にする事で、私的なチャンクを定義する事も出来ます。
この場合、デコーダには無視される事になりますが、その一方で何処の誰かが全く同じ名前で別物の私的チャンクを定義する可能性もある事は忘れてはいけません。
PNG画像において、IDATチャンクに納められる画像データは、以下に述べるデータをGZIP形式のデフレート圧縮で圧縮したものです。
画像データは、横方向のラインをデータにしたものを上のラインから順に並べたものです。
但し、インタレースを掛ける場合は、方法が異なります(この事はインタレースのところで後述します)。
横方向ラインの画像データは以下のようになります。
効率良く圧縮を行うために、ライン毎にフィルタの形式を指定する事が出来ます。
フィルタとはデータを圧縮し易くするためにデータの並びを所定の計算式によって揃えて行くものです。
フィルタは可逆的な処理で、実際に画像を表示させる際には各ライン毎にフィルタ種別のデータを見て適切な復元を行います。
1ピクセルがオクテットに満たない場合は左から上位ビット列になるように押込み、一番右端を処理した後の余りビット列は下位の側に残されます。
PNG画像では、圧縮効率を高めるため、フィルタと呼ばれる事前データ処理が行われます。
エンコーダは圧縮する前に適切なフィルタを選択して処理します。
また、デコーダは展開した後のデータをフィルタの決まりに従って復元します。
フィルタは、画像の各ライン毎に五種類のアルゴリズムの中から一つを撰ぶ事になっております。
具体的には、エンコーダは各オクテットに対してフィルタ方式で指定された値との差分をフィルタ処理後の値として利用します。
デコーダは展開後にフィルタ方式で指定された値を各オクテットに加える事で元通りの値に戻ると言う訳です。
データ処理は一切行いません。
フィルタをかけないと言えばよいと思われるかも知れませんが、PNG画像ではフィルタをかけない事(フィルタ番号のオクテットを附加しない事)は許されておらず、よって無処理のフィルタをかけるというのが正しい言い方と言えます。
左隣のピクセル値との差分を取ります。
真上のピクセル値との差分を取ります。
左隣のピクセル値と真上のピクセル値を足して 2で割った値との差分を取ります。
左隣, 真上及び左上のピクセル値のうち、最も対象となるピクセル値に近いものとの差分を取ります。
ピースとはこの方式を考案した人の名前です。
PNG画像を作成する際にフィルタを選択する場合、五種類もあるフィルタアルゴリズムから、最適なものを一行ごとに選択しなければなりません。
このため、フィルタを常に 0番(無処理フィルタ)にしているソフトウェアも少なくありません。
また、インデックスドカラーや 8ビット未満のグレイスケールの場合はフィルタの効果は殆ど無い事が知られており、従って
と言うようにすれば良いでしょう。
フルカラー画像には常にピースのフィルタを適用するようにすると良いとの事です。
実際問題として、各フィルタアルゴリズムを適用して圧縮して最も効果的なものを撰ぶ…という手法は非現実的です。
このため、PNGの仕様書ではエンコーダを作る際の指針として、以下のような最適なフィルタの見積もり方を提案しております。
この方法は、基幹技術であるデフレート圧縮(LZ77圧縮)に見られる、「価のバラつきは小さい方が圧縮し易い」という性質に基いたものと思われます。
価の合計値が小さくなれば、それだけ各ピクセルの価のバラつきが小さくなって圧縮し易くなると言う訳です。
この方法は制作者も実際に試してみましたが、概ね良好な結果となりました。
勿論、更に研究が進めばもっと適切な見積もり方も見付かるかも知れません
が、現状ではこれでも充分と言えると思われます。
実験を重ねた結果、フルカラーでのフィルタは常に「ピースのフィルタ」に固定しておいた方が、下手にフィルタを撰ぶより効率がよい事が判明しました。
PNG画像では、GIF画像同様インタレース方式をサポートしております。
インタレースPNG画像では、プログレッシヴな表示を実現するために、画像を七段階に分けて処理します。
具体的には、画像を 8ピクセルズ四方のブロックに分割して、各ブロックから段階ごとに指定されたピクセルを抽出したものを縦横に再配列したものに対して各行ごとに適切なフィルタを掛けてピクセル列にします。
ブロック内のピクセルと段階の関係は以下の通りです。
X座標 | |||||||||
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
Y座標 | 0 | 1 | 6 | 4 | 6 | 2 | 6 | 4 | 6 |
1 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | |
2 | 5 | 6 | 5 | 6 | 5 | 6 | 5 | 6 | |
3 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | |
4 | 3 | 6 | 4 | 6 | 3 | 6 | 4 | 6 | |
5 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | |
6 | 5 | 6 | 5 | 6 | 5 | 6 | 5 | 6 | |
7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 |
ところで、画像の幅または高さが 4ピクセルズ以下の場合、対応するピクセルの無い段階が生じ得ます。
この場合、当該段階はピクセルが無い以上フィルタを掛ける意味もありません。
よって、当該段階にはフィルタは掛けられず、ピクセル列も一切存在しないものとなります。
例えば、幅 4ピクセルズ、高さ 8ピクセルズの画像は以下のようになります。
インタレースPNGでは縦横を満遍無く展開して行くため、途中でも画像の内容が分かり易いのが特徴です。
しかしながら、インタレースPNG画像は、インタレースGIF画像に比べるとかなり複雑な処理になります。
特に各段階ごとに抽出したデータを処理するため、インタレースGIF画像に較べてどうしてもファイルサイズが大きくなってしまうという欠点があります。
このため、インタレースPNG画像は余り用いられる事は無いようです。
MNG(ミング)動画は「マルティプルイメージ・ネットワーク・グラフィックス」の略で、PNG画像を拡張した動画形式として、西暦2000年(平成12年)に策定されました(勧告は西暦2001年 1月)。
PNG画像の普及が遅れた最大の理由として、GIF画像がサポートしていた簡易動画機能(アニメーション)をサポートしなかった事が挙げられました。
PNG画像はあくまでも画像の規格なので簡易なものであろうと動画機能は不要だと判断した事が仇になったのです。
このため、PNG画像を拡張した動画形式の策定が行われ、生まれたのがMNG動画と言う訳です。
MNG動画の特徴は以下の通りです。
シグネーチャとチャンクと言う構成はPNG画像と全く同じです。
シグネーチャはPNG画像と区別するために新しいものが制定され、動画を実現する為に新たなチャンクが追加定義されました。
実際にはMNG動画形式としては単一の静止画PNG画像も認められます。つまり、MNG動画はPNG画像と完全に上位互換性があります。
但し、JPEG画像を組込むには予めJNG(ジング)画像と呼ばれる形式に変換する必要があります。
JNG画像は「JPEG・ネットワーク・グラフィックス」の略で、MNG動画にJPEG画像を組込めるようにするため、PNG画像/MNG動画のチャンク仕様に合わせた画像形式です。従来のJPEG画像に加えてアルファチャネルを別チャンクで組込む事も出来ます。
アニメーションGIFの場合、同じ画像でも出て来る度に挿入しなければなりません。
MNG動画では、始めに利用する画像に番号を付けて登録し、「何番の画像をどう表示させるか」というデータを並べて動画を実現します。
このため、同じ画像を使い廻す場合はアニメーションGIFより小さくなります。
しかしながら、実装しているブラウザが未だに皆無と言う状況で、もはや完全に死んだ規格となってしまいました。
その理由はいろいろ考えられますが、
MNG動画の仕様はとてつもなく複雑で、忠実に実装する事は極めて困難です。
この煩雑さ見越してか、一部を省略したMNG-LCや更に縮小したMNG-VLCと言う仕様も併せて用意されたのですが、何処かの画像作成ツールがフル規格を実装してしまうと当然ユーザエージェント側も対応せざるを得なくなります。拡張子もMIMEタイプでもサブセットとフル規格の区別は出来ず、結局フル規格を実装しないと対応出来ない恐れが出てきます。
本格的な動画を標榜するくせに音声の扱い方は全く仕様に組まれておりません。
簡単なパタパタアニメならともかく、本格的な動画と言うのであればまさに看板に偽りありの羊頭狗肉です。
一口に動画と言っても、そのレヴェルはさまざまです。
簡単なパタパタアニメならアニメーションGIFで充分です。
アニメーションGIFでは無理でもMNG動画でやれる事はフラッシュで全部出来ます。
しかも、フラッシュプレーヤの普及率はPC向けのブラウザなら98%以上にもなっております。
更にフラッシュなら音声を加えるなどMNG動画で出来ない事も出来ます。
更により本格的な動画になら、圧縮効率のよいMPEG動画やWMV動画があり、MNG動画では無理です。
こう考えるともはやMNG動画が押し退けるには余りに遅過ぎたと思われます。
APNG・アニメーションPNG画像は、PNG画像を拡張してアニメーションを実現すると言うものです。
西暦2003年(平成15年) 6月に唯一MNG動画を実装していたもじら(現・シーモンキー)がサポートを打ち切ってしまい、その後もじら開発スタッフが代わりのものとして提案したものがAPNGでした。
APNGはしばらく立ち消えとなりましたが、西暦2006年(平成18年)に再度APNGに関する開発が行われるようになりました。
しかし、PNG画像形式ワーキングティーム(W3Cなどとは直接の繋がりは無い)はPNG画像をあくまでも静止画の規格、すなわち単一の画像データのみを扱う規格とする事に固執しており、代わりに一連の画像を一枚に纏めてそこから一コマ一コマを切り出して代りばんこに表示させるモンタージュPNGや、アニメーションGIF画像にPNG形式のデータを収めた規格を提案しているようです。
APNGは、従来のPNG画像対応環境でも取扱え(この場合は静止画になる)、且つAPNG対応環境ではアニメーションとして表示されるようになっております。
APNGの具体的な構造は以下のようになります。
各コマはコマの表示位置などを指定するfcTLチャンクと、それに続く圧縮画像のチャンクの組となる。
圧縮画像のチャンクは、
で表される。
尚、fdATチャンクの形式はIDATチャンクとチャンク名以外は全く同様で、エンコーダの都合で複数チャンクとなっても良い。
この仕様に依り、
と言う訳です。
実際問題として、この規格はMNG動画とは較べ物にならないほど単純で、且つかつての目論見だったGIF画像を置き換えるために欠かせない規格と言えます。
とは言うものの、PNG画像形式ワーキングティームがこの規格について否定的な態度を取っている事から、仕様として定めたところで普及するかどうかは分かりません。
制作者はアンチPNGですので絶対に使いません。せいぜい内輪揉めで空中分解でもしてしまえばいいとさえ思っております。
しかしながら、制作者は思うにPNG画像がGIF画像を駆逐出来なかった最大の原因は、このようなPNGワーキングティームの"独善的な頭の堅さ"にあるのではないのかとさえ思えてしまいます。静止画の規格なのだから複数画像データを扱う拡張をするなと言うのは余りにも頑固過ぎます。GIF画像が成功したのは明らかに柔軟さにあったからでしょう。PNG画像は仕様は柔軟でも策定する人間はダイヤモンドより固い頭の持ち主ばかりかと思えるほどの異常な頑固者ばかりです。