All Articles

画像ファイルフォーマットの基本

画像・動画・音声処理および XR 一人アドベントカレンダー 2 日目の記事です。

はじめに

画像ファイルフォーマットの基本について調べたことをまとめます。

画像ファイルフォーマットの分類

画像ファイルフォーマットについては、Wikipedia の以下の 4 つの記事がとっかかりとして良いです。

最近よく見る画像ファイルフォーマットを分類すると、以下のようになります。

  • ビットマップ画像 (ラスター形式)

    • PNG
    • JPEG
    • GIF
    • WebP
  • ベクター画像 (ベクター形式)

    • SVG
  • その他、一緒に知っておきたいファイルフォーマット

    • PDF

順に概要を見ていきます。

ビットマップ画像 (ラスター形式)

ピクセル単位で色の情報を持っているのがビットマップ画像です。

PNG・JPEG・GIF の比較については、以下の記事が参考になります。

PNG (Portable Network Graphics)

特徴

  • 基本的にフルカラー (24 bit)
  • 可逆圧縮

なお、「フルカラー - Wikipedia」によると、24 bit カラーをフルカラーと呼ぶことが多いとのことです。

24 ビットカラー(16,777,216 色)、トゥルーカラー(truecolor, true colors)。(中略) 現代のパソコン業界では、トゥルーカラーのみをフルカラーと呼ぶことが多い。

JPEG (Joint Photographic Experts Group)

特徴

  • フルカラー (24 bit)
  • 基本的に非可逆圧縮

GIF (Graphics Interchange Format)

特徴

  • 256 色 (8 bit)
  • 可逆圧縮
  • アニメーションをサポート

WebP (ウェッピー)

WebP は、Google が開発した圧縮率の高い画像形式です。

特徴

  • 可逆圧縮・非可逆圧縮

参考: WebP とその他画像形式の違いとは?3 つのメリットと変換方法解説

ベクター画像 (ベクター形式)

画像を幾何学的な図形として表現するのがベクター形式です。

SVG (Scalable Vector Graphics)

ベクター画像と言えば SVG だと思います。

SVG は、XML ベースのベクター画像形式です。

その他、一緒に知っておきたいファイルフォーマット

PDF (Portable Document Format)

PDF は、Adobe が開発した文書フォーマットです。

現在は ISO 32000-1 として標準化されています。

PDF 自体は画像ではないです (画像に分類されているケースもあります) が、内部にベクター画像やラスター画像を保持することもできます。

参考: Portable Document Format - Wikipedia

画像ファイルをよく見てみる

さて、これだけで終わっては面白くないので、画像ファイルをよく見てみたりしようと思います。

PNG

File:Lenna (test image).png - Wikipedia」からレナ画像を取得します。

curl https://upload.wikimedia.org/wikipedia/en/7/7d/Lenna_%28test_image%29.png > Lenna.png

hexdump で見てみると、以下のようになります。

$ hexdump -C Lenna.png | head
00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|
00000010  00 00 02 00 00 00 02 00  08 02 00 00 00 7b 1a 43  |.............{.C|
00000020  ad 00 00 00 01 73 52 47  42 00 ae ce 1c e9 00 07  |.....sRGB.......|
00000030  3a a1 49 44 41 54 78 da  ec e1 5d 92 6d 5b 92 1d  |:.IDATx...].m[..|
00000040  e6 8d e1 ee 73 ae b5 23  e2 9c 7b 33 ab 20 08 e4  |....s..#..{3. ..|
00000050  8b 5a 20 a3 8c 46 51 a4  f1 4f 25 a3 99 3a 23 a3  |.Z ..FQ..O%..:#.|
00000060  00 ea 55 0d 50 e3 d4 00  51 a4 c1 00 92 48 20 ab  |..U.P...Q....H .|
00000070  b2 f2 de 7b 22 f6 5e 6b  4e 77 1f 4a b5 03 f9 7d  |...{".^kNw.J...}|
00000080  fc d7 ff af ff 27 80 c2  09 6d b7 0b af b4 c7 a1  |.....'...m......|
00000090  24 a6 77 5e ae a3 b4 3b  7f f8 e3 bd 92 bd 16 c6  |$.w^...;........|

Portable Network Graphics - Wikipedia」によると PNG の先頭 8 バイトは

「89 50 4E 47 0D 0A 1A 0A」

とのことですが、確かにその通りになっています。

なお、「vim でバイナリを編集する - Qiita」という記事を参考に、vim -b:%!xdd でバイナリを見てみると、最初の 10 行は以下のようになります。

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0200 0000 0200 0802 0000 007b 1a43  .............{.C
00000020: ad00 0000 0173 5247 4200 aece 1ce9 0007  .....sRGB.......
00000030: 3aa1 4944 4154 78da ece1 5d92 6d5b 921d  :.IDATx...].m[..
00000040: e68d e1ee 73ae b523 e29c 7b33 ab20 08e4  ....s..#..{3. ..
00000050: 8b5a 20a3 8c46 51a4 f14f 25a3 993a 23a3  .Z ..FQ..O%..:#.
00000060: 00ea 550d 50e3 d400 51a4 c100 9248 20ab  ..U.P...Q....H .
00000070: b2f2 de7b 22f6 5e6b 4e77 1f4a b503 f97d  ...{".^kNw.J...}
00000080: fcd7 ffaf ff27 80c2 096d b70b afb4 c7a1  .....'...m......
00000090: 24a6 775e aea3 b43b 7ff8 e3bd 92bd 16c6  $.w^...;........

PNG のバイナリを Vim などで編集するのは、圧縮されていたりするためとても難しいです。

Python の Pillow などのライブラリを使うと 8bit ずつの RGB などを簡単に取得できたり編集できたりしますが、内部で色んなことをやってくれているんだなと実感します。

そのあたりについて、以下の記事は自前でいろいろ処理していてとても面白いです。

SVG

SVG 入門 - とほほの WWW 入門」を参考に、ちょっとした SVG ファイルを作ってみます。

SVG はただのテキストファイルなので、エディタで作ることも可能です。

以下のような SVG ファイルを作成すると…

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="200" height="200">
  <circle cx="100" cy="100" r="100" stroke="black" fill="#fff" stroke-width="1" />
</svg>

svg_circle.svg

円が表示されました。

PDF

最後に、PDF のファイルフォーマットについて面白い記事をいくつか見かけたので、リンクを貼っておきます。

おわりに

以上、画像ファイルフォーマットの基本について調べたり、少し中身を見てみました。

画像ファイルをバイナリレベルで見るようなことはなかなかないと思いますが、少し覗いてみようとするだけでも結構勉強になりました。

関連して、画像処理のアルゴリズムをまとめている良さそうなサイトも見かけたので、リンクを貼っておきます。