2019/01/25

Canvasで任意の色に近い色をカラーパレットから取得し画像を減色する

Canvasで表現できる色は、RGBがそれぞれ0〜255の値を取るので、256*256*256の16,777,216種類ある。(※Alphaについては考えない)
そのまま表示すれば実物に近い画像になるのだが、減色したいときもある。(レトロ感をだす画像処理フィルターとか)

そこで、任意の色に近い色をカラーパレットから取得し画像を減色する方法をまとめる。

ユークリッド距離を使って色差を求める


近い色を取得する方法はいくつかあるのだが、今回はその中でも一番手軽に使えるユークリッド距離を用いた減色をする。

色におけるユークリッド距離の求め方は、以下のようになる。
これだけでも良いのだが、人間の目は「緑 > 青 > 赤」の順に敏感なのでそれぞれの色に赤:30%, 緑:59%, 青:11%の重み付けをする。(この比率にはいろんなパターンがあるが、今回はWikipediaに乗っていた比率を使う)
// 色差を求める
const distance = Math.pow(((r2 - r1) * 0.3), 2) + Math.pow(((g2 - g1) * 0.59), 2) + Math.pow(((b2 - b1) * 0.11), 2));



カラーパレットから近い色を取得する


// カラーパレット
const palette = ["DF0413", "059543", "007DC6"];

// HEXカラーコードをRGBに変換する
function convertToRGB(hex) {
  return {
    r: parseInt(match[0], 16),
    g: parseInt(match[1], 16),
    b: parseInt(match[2], 16)
  };
}

// ユークリッド距離で色差をもとめる
function calcDelta(t, p) {
  return (
    Math.pow((p.r - t.r) * 0.3, 2) +
    Math.pow((p.g - t.g) * 0.59, 2) +
    Math.pow((p.b - t.b) * 0.11, 2)
  );
}

// カラーパレットから近い色を取得する
function chooseColor(palette, hex) {
  // 元の色(RGB)
  const rgb = convertToRGB(hex);

  let color;
  let delta = Number.MAX_SAFE_INTEGER;

  // カラーパレットの色と元の色の色差が一番小さい(似ている)色を選ぶ
  palette.forEach(p => {
    // カラーパレットの色(RGB)
    const prgb = convertToRGB(p);
    const d = calcDelta(rgb, prgb);
    if (d < delta) {
      color = p;
      delta = d;
    }
  });

  return color;
}


参考サイト





以上

written by @bc_rikko

0 件のコメント :

コメントを投稿