画像で使用している色の数を取得する[色数の取得]
GIF/PNG/JPEGなどの画像ファイルで使用されている色の数「色数」をJavascriptで取得する方法です。難しいように見えて実は簡単に取得できます。
色数の取得アルゴリズム
「色数」は10年ぐらい「しきすう」と読んでいたのですが、この記事を書くにあたり国語辞典で調べてみたら「いろかず」と読むらしいです。(恥ずかしい)
それは、さておき、色数の取得アルゴリズムです。
JavascriptではgetImageData()というメソッドで画像データを丸ごと取得できますので、スキャンライン(Scanline)やら画像の横幅の走査線、パディングなどは無視して単に色をカウントできます。
カウント方法は全ての色を連想配列に格納して、その連想配列の数をカウントするという手法になります。
連想配列自体、for文より少し重いですが、比較的、高速になります。
次は画像の色数を取得するコードとなります。
プログラムコード
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <canvas id="MyCanvas"></canvas> <img id="img_test" src="test.gif" style="display:none;"> <script> // キャンバスの取得 var canvas = document.getElementById("MyCanvas"); if (canvas.getContext) { // コンテキストの取得 var ctx = canvas.getContext("2d"); // イメージの取得 var image = document.getElementById("img_test"); // イメージが読み込まれた image.addEventListener("load", function () { canvas.width = image.width; canvas.height = image.height; // キャンバスに画像を描画 ctx.drawImage(image,0,0); // キャンバスのイメージデータを取得 var imagedata = ctx.getImageData(0, 0, image.width, image.height); // 使用している色を連想配列へ格納 var cnt = 0; var colors = new Object; for(var i = 0; i< image.height;i++){ for(var j = 0; j< image.width;j++){ colors['R' + imagedata.data[cnt] + 'G' + imagedata.data[cnt+1] + 'B' + imagedata.data[cnt+2] ] = 1; cnt = cnt + 4; } } // 連想配列の個数をカウント var cnt = 0; for (var key in colors) { cnt++; } alert('この画像は' + cnt + '色を使用しています。'); },false); } </script> </body> </html>
test.gifの部分は画像を適宜、用意して変更して下さいね。
[実行画面]

注意事項
Chromeをお使いの方はローカルで実行するとセキュリティエラーが発生します。このエラーを回避するには「Uncaught SecurityErrorのエラー回避方法」をご覧ください。
問題点
このコードはChrome、Firefoxでは高速に動作します。ですが、IE/Edgeでは遅いです。IE/EdgeはgetImageData()で取得したimagedata.dataのアクセスが非常に低速なのです。
試しにIE/Edgeで画像のアルファブレンドを試してみると1000ms~2000msぐらいになります。対して、Chrome、Firefoxだと100ms未満となります。
ブラウザによってJavascriptのエンジンの性能がここまで異なると悪いことを考えてしまいます。MSはブラウザを意図的に低速にして新しいパソコン(CPUやメモリ)を購入させてWindowsも一緒に売るようにしてるしか思えないです^^;
いずれにせよ、私はJavascriptで画像の減色処理をやる予定なのでIE/Edgeでも高速になる方法を探してみますね。
関連記事
前の記事: | Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. のエラー回避方法 |
次の記事: | canvasに画像をタイル状で並べる[画像を繰り返し塗りつぶす] |