SVG ファイル形式
Scalable Vector Graphics。XML ベースのベクター画像形式。
- MIME タイプ
- image/svg+xml
- 拡張子
- .svg
- カテゴリ
- 画像
マジックナンバー(ファイル署名)
`<svg` 要素を含むプレーンテキストの XML(多くは先頭に `<?xml` が付きます)。
SVG 形式について
SVG は画像をベクター図形として XML で記述するため、どんなサイズに拡大してもぼやけず、CSS でスタイル指定やアニメーションもできます。プレーンテキストなのでバイナリのマジックナンバーはなく、先頭付近の XML 宣言か `<svg` 要素で判別します。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 3 | UTF-8 byte-order mark | EF BB BF。省略可能で、XML が宣言より前に許している唯一のものです。今も拒否する古いパーサやサーバ設定がわずかにあり、それ以外は正しい SVG が描画されない原因として繰り返し登場します。 |
| 0 | 2 | UTF-16 byte-order mark | リトルエンディアンなら FF FE、ビッグエンディアンなら FE FF。UTF-8 のマークと違ってこちらは省略できません。XML は UTF-16 のコンテンツに BOM を要求します。UTF-16 の SVG は珍しく、1 文字 1 バイトを前提にしたツールをことごとく壊します。 |
| 0 | 5 | XML declaration opener | 3C 3F 78 6D 6C、宣言を開始する文字列です。XML は、宣言を書くならドキュメントの本当に先頭になければならないと定めています。つまりオフセット 0、UTF-8 BOM があるならオフセット 3 です。UTF-8 のコンテンツでは省略可能なので、検出器がこれを必須にすることはできません。 |
| 0 | 5 | DOCTYPE opener | 3C 21 44 4F 43。Illustrator や Inkscape の古いファイルは、SVG 1.1 の DTD を指す DOCTYPE で始まります。BOM も宣言もない場合だけオフセット 0 に来て、そうでなければ宣言の直後に置かれます。SVG 2 で DTD は廃止されたので、新しいファイルには付きません。 |
| 0 | 4 | Root element start tag | 3C 73 76 67。これがオフセット 0 に来るのは、BOM も宣言も DOCTYPE も先頭コメントもないファイルだけです。XML はその 4 つすべてを手前に許しているので、オフセットは本当に固定されません。検出器は位置を調べるのではなく、先頭数百バイトからこの文字列を探します。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| GZIP | .svgz は gzip した SVG なので、1F 8B 08 で始まり、読めるマークアップはどこにもありません。サーバは gzip の Content-Encoding ヘッダを付けて送り、ブラウザは透過的に展開します。hex エディタで見れば単なる gzip メンバで、書き手がファイル名を入れていればそれが .svg で終わっています。 |
| XML | SVG は XML なので、汎用の XML 判定はすべて通り、そして何も分かりません。両者を分けるのはルート要素の名前だけです。宣言・DOCTYPE・コメント・処理命令ではない最初のタグが svg 要素でなければなりません。別のルートの中に入れ子になった svg 要素は、SVG ドキュメントではありません。 |
| HTML | HTML5 は svg 要素のインライン記述を許しているので、HTML ページが SVG を識別するのとまったく同じバイト列を含むことがあります。ルートが実際に何かを見てください。先頭に DOCTYPE html があるか html 開始タグがあれば、それは絵を含んでいるだけの HTML で、image/svg+xml ではなく text/html として配信しなければなりません。 |
| PNG | バイトレベルでは 89 50 4E 47 と読めるテキストなので取り違えようがないのに、実務では取り違えが絶えません。いくつかのデザインツールの SVG として書き出しが、中身は base64 の PNG を抱えた image 要素 1 つだけ、という SVG を吐くからです。ファイルとしては本物の SVG で、中のグラフィックはラスターのままなので、拡大しても鮮明にはなりません。 |
よくある壊れ方
- 野良のアンパサンド。XML のエラー処理は容赦がないので、href 属性の URL の中にエスケープしていない & が 1 つあるだけでドキュメント全体が整形式でなくなり、ブラウザは絵の 95 パーセントを描くのではなく何も描きません。毎回 & と書く必要があります。
- 名前空間の欠落。ルート要素から http://www.w3.org/2000/svg を指す xmlns 属性を落としても、XML としては正しく解析でき、テキストエディタでも開けますが、どのブラウザでも真っ白になります。手で編集した SVG が突然動かなくなる原因としてはいちばんよくあるものです。
- エンコーディングの不一致。宣言は UTF-8 と言っているのに、ファイルは Latin-1 や Shift_JIS で保存されている場合です。text 要素が文字化けするか、最初の不正なシーケンスでパーサが中断します。見るべきバイトはヘッダの中ではなく、text 要素の中身のほうです。
- 途中切れ。閉じ svg タグが途中までしか書かれていないのは致命的な整形式エラーなので、途中で切れた PNG と違って部分的な描画すら見られません。手がかりはファイルの末尾で、無事な SVG は閉じ svg タグと、たいてい改行で終わっています。
- あるべきでない場所のバイトオーダーマーク。別のエンコーディングを名乗る宣言の手前にあれば矛盾になりますし、HTML ページにインライン展開される SVG の中にあれば、その 3 バイトが目に見える空白になって周囲のレイアウトをずらします。
この形式の現在地
SVG はウェブが唯一合意できたベクター画像形式で、25 年たった今も競合が存在しません。アイコン、ロゴ、グラフ、図解、イラストが SVG で配られるのは、1 ファイルでどの画素密度でも鮮明さを保ち、CSS から色を変えられるからです。2012 年ごろに同じ問題を解いたアイコンフォントは、事実上消えました。SVG が向かないのは写真です。写真をトレースすると、元の JPEG より大きくて描画も遅いファイルができあがります。数千を超えるパスを持つイラストも同様で、要素ごとの DOM のコストがサイズ面の利得を上回ります。スクリプトや外部参照を持てるので、攻撃面としても現役です。ユーザーから受け取ったファイルは、配信し返す前に必ずサニタイズしてください。
SVG ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
SVG と混同しやすい形式です。先頭バイトを見比べてください。