カラーパレットのソート、整列[検証]
ペイント系アプリや画像ファイルで使用される256色のカラーパレットをソート、整列する方法を検証してみました。検証方法はRGB、HSL色空間と色相、彩度、明度のソートによる整列です。
ネットで探しても全く記事が見つかりませんでしたので試しました。
原パレット
検証対象となる256色のカラーパレットです。パレットの色は先頭から「基本16色」「Web216色」で残りは「黒色」となります。
次のJavascriptのコードは検証用です。初期値は「原パレット」を生成します。色空間によるソートの検証をする場合はwindow.onload()イベントの部分を後述するコードに変更します。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <div id="PaletteArea"></div> <script> var palette = new Array(); // Web216色 + 基本16色 + 黒 var src_palette =["#000000","#ffffff","#c0c0c0","#808080","#800000","#ff0000","#800080","#ff00ff","#008000","#00ff00","#808000","#ffff00","#000080","#0000ff","#008080","#00ffff", "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033","#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff","#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399","#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333","#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff","#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699","#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633","#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff","#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999","#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33","#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff","#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99","#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33","#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff", "#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000", "#000000","#000000","#000000","#000000","#000000","#000000","#000000","#000000"]; window.onload = function(){ Original(); craetePaletteArea(); } // パレットエリアの作成 function craetePaletteArea() { var html = '<table> '; for (var i = 0; i < 16; i++) { html += '<tr>'; for (var j = 0;j < 16; j++) { html += '<td>'; html += '<div style="width:14px;height:14px;">' ; html += '<div'; html += ' style="width:12px;height:12px;background-color:'; html += palette[(i*16)+j] + ';"'; html += '></div>'; html +='</div>'; html += '</td>'; } html += '</tr>'; } html += '</table>'; document.getElementById('PaletteArea').innerHTML = html; } // RGB色空間からHSL色空間へ変換する // r(red) : 赤色 0-255の値 // g(green): 緑色 0-255の値 // b(blue) : 青色 0-255の値 function rgb2hsl(r, g, b){ var max = Math.max(r, g, b); var min = Math.min(r, g, b); var hsl = {'h':0, 's':0, 'l':(max + min) / 2}; // L(明度) if (max != min) { // H(色相) if (max == r) hsl.h = 60 * (g - b) / (max-min); if (max == g) hsl.h = 60 * (b - r) / (max-min) + 120; if (max == b) hsl.h = 60 * (r - g) / (max-min) + 240; // S(彩度) if (hsl.l <= 127){ hsl.s = (max - min) / (max + min); }else{ hsl.s = (max - min) / (510 - max - min); } } if (hsl.h < 0){ hsl.h = hsl.h + 360; } hsl.h = Math.round(hsl.h); hsl.s = Math.round(hsl.s * 100); hsl.l = Math.round((hsl.l / 255) * 100); return hsl; } // backgroundColorからRGB値を取得して配列で返す function Color2RGB(backgroundcolor) { // [IE/Chrome/FireFox] rgb(255,255,255)の文字列形式からRGBを取得する var result = backgroundcolor.replace("rgb(",""); result = result.replace(")",""); result = result.replace(/ /g,""); result = result.split(","); // [Opera] #ffffff の文字列形式からRGBを取得する var buffer; if (result[0][0] == '#'){ buffer = new Array(); buffer[0] = parseInt(result[0].slice(1,3),16); buffer[1] = parseInt(result[0].slice(3,5),16); buffer[2] = parseInt(result[0].slice(5,7),16); result = buffer; } result[0] = parseInt(result[0],10); result[1] = parseInt(result[1],10); result[2] = parseInt(result[2],10); return {'r':result[0],'g':result[1],'b':result[2]}; } // 原パレット function Original(){ for (var i = 0; i < src_palette.length; i++) { palette[i] = src_palette[i]; } } // RGBのソート function rgbSort(){ src_palette.sort(function(a,b){ var a_rgb = Color2RGB(a); var b_rgb = Color2RGB(b); if(a_rgb.r < b_rgb.r) return 1; if(a_rgb.r > b_rgb.r) return -1; if(a_rgb.g < b_rgb.g) return 1; if(a_rgb.g > b_rgb.g) return -1; if(a_rgb.b < b_rgb.b) return 1; if(a_rgb.b > b_rgb.b) return -1; return 0; }); for (var i = 0; i < src_palette.length; i++) { palette[i] = src_palette[i]; } } // HSLによるソート function hslSort(){ var rgb,hsl; var hsl_palette = new Array(); for (var i = 0; i < src_palette.length; i++) { rgb = Color2RGB(src_palette[i]); hsl = rgb2hsl(rgb.r,rgb.g,rgb.b); hsl_palette[hsl_palette.length] = {'h':hsl.h, 's':hsl.s, 'l':hsl.l, 'rgb':src_palette[i]}; } hsl_palette.sort(function(a,b){ if(a.h < b.h) return 1; if(a.h > b.h) return -1; if(a.s < b.s) return 1; if(a.s > b.s) return -1; if(a.l < b.l) return 1; if(a.l > b.l) return -1; return 0; }); for (var i = 0; i < hsl_palette.length; i++) { palette[i] = hsl_palette[i].rgb; } } // HSLのHによるソート function hsl_h_Sort(){ var rgb,hsl; var hsl_palette = new Array(); for (var i = 0; i < src_palette.length; i++) { rgb = Color2RGB(src_palette[i]); hsl = rgb2hsl(rgb.r,rgb.g,rgb.b); hsl_palette[hsl_palette.length] = {'h':hsl.h, 's':hsl.s, 'l':hsl.l, 'rgb':src_palette[i]}; } hsl_palette.sort(function(a,b){ if(a.h < b.h) return 1; if(a.h > b.h) return -1; return 0; }); for (var i = 0; i < hsl_palette.length; i++) { palette[i] = hsl_palette[i].rgb; } } // HSLのSによるソート function hsl_s_Sort(){ var rgb,hsl; var hsl_palette = new Array(); for (var i = 0; i < src_palette.length; i++) { rgb = Color2RGB(src_palette[i]); hsl = rgb2hsl(rgb.r,rgb.g,rgb.b); hsl_palette[hsl_palette.length] = {'h':hsl.h, 's':hsl.s, 'l':hsl.l, 'rgb':src_palette[i]}; } hsl_palette.sort(function(a,b){ if(a.s < b.s) return 1; if(a.s > b.s) return -1; return 0; }); for (var i = 0; i < hsl_palette.length; i++) { palette[i] = hsl_palette[i].rgb; } } // HSLのLによるソート function hsl_l_Sort(){ var rgb,hsl; var hsl_palette = new Array(); for (var i = 0; i < src_palette.length; i++) { rgb = Color2RGB(src_palette[i]); hsl = rgb2hsl(rgb.r,rgb.g,rgb.b); hsl_palette[hsl_palette.length] = {'h':hsl.h, 's':hsl.s, 'l':hsl.l, 'rgb':src_palette[i]}; } hsl_palette.sort(function(a,b){ if(a.l < b.l) return 1; if(a.l > b.l) return -1; return 0; }); for (var i = 0; i < hsl_palette.length; i++) { palette[i] = hsl_palette[i].rgb; } } </script> </body> </html>
RGB
RGBの各値を降順でソートした結果です。
window.onload = function(){ rgbSort(); craetePaletteArea(); }
HSL
HSLの各値を降順でソートした結果です。
window.onload = function(){ hslSort(); craetePaletteArea(); }
色相
HSLの色相のみを降順でソートした結果です。
window.onload = function(){ hsl_h_Sort(); craetePaletteArea(); }
彩度
HSLの彩度のみを降順でソートした結果です。
window.onload = function(){ hsl_s_Sort(); craetePaletteArea(); }
明度
HSLの明度のみを降順でソートした結果です。
window.onload = function(){ hsl_l_Sort(); craetePaletteArea(); }
検証結果
カラーパレットをRGB、HSV色空間でソートすると数値上は近い数字に並び替えは可能です。しかし、人間の目でみて納得する綺麗なグラデーションにはならない。
但し、グレースケールなど別のパレットを使用すると効果があるかも知れないです。
HSVはHSLとほとんど同じなので検証からはずしました。また、これとは別にLAB色空間でも試しましたが作業時間オーバーで断念しました。LABは画像の近似画像の検出などに重宝すると思います。
パレットを人間の目でみて綺麗に整列させるロジックは考えるだけで面白そうですので、また時間ができたら試したいと思います。
LAB色空間に関する外部リンク
関連記事
前の記事: | 色相環と12色相環[作成と計算式] |
次の記事: | 12色相環グラデーション |