PNGファイルの仕組みを知りたいと思ったことはありませんか? いや? とにかく教えます
PNG(Portable Network Graphics)形式はGIFの代替となるために1995年に発明され、1996年にバージョン1.0のリリースで既にW3Cにより本格的なネットワーク形式として推奨されました。 今日、PNGはWebグラフィックの主要な形式の1つです。
カットの下には、PNGファイルの構造の一般的な説明、一定数の回路図画像、準備があります 16進エディタで、そしてもちろん、仕様へのリンクで。
一般的な構造
最も一般的な形式のPNG構造を次の図に示します。
つまり、ファイルは署名といくつかのブロック(チャンク、チャンク)で構成され、各ブロックにはいくつかの情報が含まれています(KO!に感謝)。 しかし、署名がチャンクの1つと見なされないのはなぜですか? よく見てみましょう。
ファイル署名
PNGファイルの署名は常に同じで、8バイトで構成され、(16進レコードで)を表します
89 50 4E 47 0D 0A 1A 0A
これはどういう意味ですか?
- 89は非ASCII文字です。 PNGがテキストファイルとして認識されないようにします。逆も同様です。
- 50 4E 47-PNGからASCIIレコード。
- 0D 0A-CRLF(キャリッジリターン、ラインフィード)、DOSスタイルのラインフィード。
- 1A-DOSモード(ファイルの終わり)でファイルの出力を停止します。これにより、テキスト形式のマルチキロバイトの画像が抜け落ちません。
- 0A-LF、Unixスタイルのラインフィード。
チャンク
チャンクは、ファイルを構成するデータブロックです。 各チャンクは4つのセクションで構成されます。
これらのセクションを順番に分析します。
長さ
まあ、長さで、すべてが明確に見える。 データブロックの長さの単なる数値。
タイプ(名前)
タイプではもう少し面白いです。 タイプは、大文字と小文字が区別される4つのASCII文字です。 チャンク名の文字レジスタ(数値レコードの5番目のビット)は、理由により異なります-これらは、デコーダに追加情報を伝えるフラグです。
- 最初の文字の大文字と小文字は、指定されたチャンクがクリティカル(大文字)か補助(小文字)かを決定します。 重要なチャンクは各デコーダーで認識される必要があります。 デコーダーは、タイプを認識できないクリティカルチャンクに遭遇した場合、エラーで実行を完了する必要があります。
- 2番目の文字ケースは、チャンクの「パブリシティ」(大文字)または「プライバシー」(小文字)を定義します。 「パブリック」チャンクは公式であり、文書化され、ほとんどのデコーダーによって認識されます。 しかし、突然特定の情報をエンコードする必要がある場合は、チャンクの名前の2番目の文字を小さくしてください。
- 3番目の文字レジスタは将来の目的のために予約されています。 標準の異なるバージョンを区別するために使用されることを前提としています。 バージョン1.0および1.1の場合、3番目の文字は大きい必要があります。 (突然!)小さいことが判明した場合、現在のすべてのデコーダーは、チャンクと認識されていない他のすべてのアクションで動作する必要があります(つまり、チャンクが重大な場合はエラーで終了するか、そうでなければスキップします)。
- 4番目の文字の場合は、認識できない編集者がこのチャンクをコピーできることを意味します。 レジスタが低い場合、ファイルの変更の程度に関係なくチャンクをコピーできます。それ以外の場合(大文字)は、変更中に重要なチャンクが影響を受けなかった場合にのみコピーされます。
理解を深めるために、テキストを含むチャンクの例を使用してフラグを見てみましょう。
以下は、簡単な説明付きのチャンクタイプのリストです。
重要なチャンク
- IHDR-ファイルヘッダー。画像に関する基本情報が含まれています。 最初のチャンクでなければなりません。
- PLTE-パレット、色のリスト。
- IDAT-実際には画像が含まれています。 画像は、ストリーミング用に複数のIDATチャンクに分割できます。 各ファイルには、少なくとも1つのIDATチャンクが必要です。
- IEND-最終チャンク。ファイルの最後でなければなりません。
補助チャンク
- bKGD-このチャンクは前景色を設定します。
- cHRMは 、 CIE 1931色空間を指定するために使用されます。
- gAMA-ガンマを定義します。
- hIST-このチャートは、ヒストグラムまたは画像の各色の合計内容を保存できます。
- iCCP - ICCカラープロファイル
- iTXt-場合によっては圧縮された、オプションの言語タグ付きのUTF-8のテキストが含まれます。 キーワード「XML:com.adobe.xmp」を含むiTXtチャンクには、 Extensible Metadata Platform(XMP)が含まれる場合があります。
- pHYs-画像の推定ピクセルサイズやアスペクト比が含まれます。
- sBIT (有意ビット)-デコードを容易にするために、画像の「色の正確さ」(色の精度)(白黒、フルカラー、透明度のある白黒など)を定義します。
- sPLT-すべての色が使用できない場合に使用するパレットを提供します。
- sRGB-標準のsRGBスキームの使用を示します。
- sTERは、立体画像のインジケータです。
- tEXt - ISO / IEC 8859-1形式のテキストを含むことができ、各チャンクに1つの名前=値のペアがあります。
- tIME-最後の画像変更の日付を保存します。
- tRNS-透明度情報が含まれています。
- zTXtは、tEXtと同じ制限を持つ圧縮テキストです。
詳細は仕様に記載されています。
CRC
CRC-32チェックサム。 ところで、先日、Windowsでの計算に関するトピックがありました。
最小PNG
一般的な構造が整理されています。 次に、必要なチャンクのコンテンツを分析します。 しかし、それらのうちどれが必須であるか(クリティカルではない、デコーダーによって認識される必要があり、各ファイルに存在しない)、および最小のPNGファイルはどのように見えますか? そして、ここに方法があります:
Ihdr
IHDRのデータブロックには、次のフィールドが含まれています。
- 幅、 4バイト
- 高さ、 4バイト
- ビット深度、サンプルあたりのビット数(ピクセルではない)、 1バイトを決定
- カラータイプ。3つのフラグ1(パレットを使用)、2(モノクロ画像ではなくカラーを使用)、および4(アルファチャネルが存在)、 1バイトで構成されます。
- 圧縮方法。 現時点では、値0のみが利用可能です-deflateアルゴリズムによる圧縮。 値が0以外の場合、チャンクは認識されていないと見なされ、デコーダーはエラーを報告します。 1バイト
- ろ過方法。 圧縮の場合と同様に、現時点ではゼロにしかできません。 1バイト
- インターレース方式。 データ転送順序を定義します。 現在、2つの値(0(インターレースなし)と1( Adam7インターレース))を使用できます。 1バイト
Adam7インターレースは、ウィキペディアの画像を完全に示しています(はい、PNGに関する記事のGIF)。
IEND
ファイルの終わりを示します。このチャンクのデータブロックには何も含まれていません。
IDAT
ヘッダーの圧縮方法フィールドに従ってエンコードされたデータが含まれます。 デコードアルゴリズムは、この記事の範囲を超えています(ただし、必要に応じて、次の記事に記載することもあります)が、ここでは非常によく(そしてロシア語で)説明しています 。
したがって、最も単純なPNGファイル(たとえば )は次のとおりです。
おわりに
この記事を書くとき、私は読者にPNGファイルの構造に関する一般的な知識を与えるタスクを設定しました。より深い理解のために、 仕様を読むことが推奨されます。
JPEG構造に関するハブのトピック: habrahabr.ru/blogs/algorithm/102521
GIF構造に関するハブのトピック: habrahabr.ru/blogs/algorithm/127083
ご清聴ありがとうございました。どんな批判も喜んでいます!