解説
インデックスカラーは、色のインデックス(索引)を持ち、各画素ではその色を参照することで画像を表現する方式です。このインデックスのことを、カラーマップやパレットと呼びます。
Web用の画像ではGIFがインデックスカラーの代表的な形式です。色数を減らすとファイルサイズが劇的に軽くなるのが特徴になります。
例として、画素ごとにRGBの値を持つ画像と、16色のインデックスカラーの画像のデータ量の違いを挙げます。
画素ごとにRGBの値を持つ画像:
- 1画素あたりRGBを持つので3byte。
- 横640、縦480の画像は307,200画素
- 307,200画素×3byte÷1024=900KB
16色のインデックスカラーの画像:
- 1画素あたりRGBを持つので3byte。
- 16個のカラーマップで48byte。
- 1画素は16色の参照なので4bit(1/2byte)。
- (48+307,200画素×1/2byte)÷1024=150.046 KB
多くの場合、インデックスの数は、2のn乗で最大256個になります。
サンプル
インデックスカラーを利用するコードを、JavaScriptで簡単に書いてみます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>「インデックスカラー」のサンプル</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
// window.atob, window.btoa を利用(IEは10以降で動作)
$(function() {
// GIF画像のバイナリを取り出し
var mime = "data:image/png;base64,";
var img1 = $("#img1").attr("src").slice(mime.length);
var img1Dec = window.atob(img1).split("");
// カラーマップを書き換え
img1Dec[13] = String.fromCharCode(0xff);
img1Dec[14] = String.fromCharCode(0x80);
img1Dec[15] = String.fromCharCode(0x00);
img1Dec[16] = String.fromCharCode(0x00);
img1Dec[17] = String.fromCharCode(0x80);
img1Dec[18] = String.fromCharCode(0xff);
// GIF画像のバイナリをBASE64化
var img2Enc = window.btoa(img1Dec.join(""));
var img2 = mime + img2Enc;
$("#img2").attr("src", img2);
});
</script>
</head>
<body>
<img id="img1" src="data:image/png;base64,R0lGODlhIAAgAIAAAAAA
AP///yH5BAAAAAAALAAAAAAgACAAAAJsRI6ZYOpn2kNNziCts1rpDm0T2IGYOC7XSa2sqb
Iu41Kwdy95KF/VHEu1hEEPyvgoEXnLW6b2A+4gU0yVVjvtoqunr3hkIsHDcdksNjvJyG16
dI1nrVnut5dkn2HKPPr9ZvLRpcfkhpcnV1cAADs=">
<img id="img2">
</body>
</html>
