画像を和色のみの構成に変換する html を公開してみる

画像を和色のみにした場合に
どんな見た目になるかどうかを
軽くチェックするための html を
作成しましたので
皆さんの役に立てばと思い
公開してみようと思います。

[オンラインで動作するバージョンはこちら](https://uni928.github.io/SephirothImageToSpecificColor/)

[ダウンロードはこちら(BOOTH)](https://giftedstyle.booth.pm/items/6002643)
[ダウンロードはこちら(Google Drive)](https://drive.google.com/file/d/1MReoq0hTMXFdpS28ha2z-vklwN1-l_3w/view?usp=sharing)

[洋色バージョンのダウンロードはこちら](https://drive.google.com/file/d/1j606X7SGYo3SqLfla0iqvL1NouyvDL4Y/view?usp=sharing)
[セーフカラーバージョンのダウンロードはこちら](https://drive.google.com/file/d/1B9ov__zccNbMertMr1yUYAQPh_fOheto/view?usp=sharing)

***

このアプリケーションの見た目
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3752886/711fec21-640b-9914-928c-1a18aa1ceeee.png)

***

この html の説明

画像を和色のみにした場合に
どんな見た目になるかどうかを
軽くチェックする html です。

画像ファイルを選択すると
左右にその画像が展開されます。
そして右側の画像が和色に変換されていきます。

境界線が乱れるため
この html で変換した物を
完成品にするのは難しいですが
画像を修正する際の指標にする事ができます。

[このサイト](https://www.colordic.org/w) に載っているいずれかの色に変換します。

***

この html ファイルのコード

この html ファイルは
下記のコードで動いています。

html ファイルを新規作成して
中身をこの内容にしても動作します。

```html:使用したコード
<html lang="ja">
<head>
    <title>画像を和色のみの構成にするサイト | Gifted Style</title>
    <meta name="description" content="画像を和色のみの構成にするサイトです。"/>
    <style>
.progress {
  border-radius: 30px;
  height: 40px;
  background: #ddd;
  overflow: hidden;
}
.bar {
  background: #FFC100;
  border-radius: inherit;
  height: 100%;
  width: 0%;
  transition: 2s;
}
    </style>
</head>
<body>
<img src="" id="preview">
<canvas id="canvas"></canvas>
<canvas id="canvas2"></canvas></br>
<input type="file" accept="image/*" id="getfile"></br>
<div class="progress">
  <div class="bar" id="Bar"></div>
</div></br></br>
このサイトは画像を和色のみにした場合に</br>
どんな見た目になるかどうかを軽くチェックするサイトです。</br></br>
画像ファイルを選択すると</br>
左右にその画像が展開されます。</br>
そして右側の画像が和色に変換されていきます。</br></br>
境界線が乱れるため</br>
このサイトで変換した物を</br>
完成品にするのは難しいですが</br>
画像を修正する際の指標にする事ができます。</br></br>
<a href="https://www.colordic.org/w" target="_blank">このサイト</a> に載っているいずれかの色に変換します。</br></br>
3 番目に出現する画像は</br>
2 番目の画像のノイズ削除処理をしたものです。</br>
5 × 5 のメディアンフィルタです。</br></br>
<script>
function MyThread(i, ctx, canvas) {
for(let j = 0; j < canvas.height; j++) {
          const imageData = ctx.getImageData(i, j, 1, 1);
          let r = imageData.data[0];
          let g = imageData.data[1];
          let b = imageData.data[2];
          let a = imageData.data[3];
          let array = ["#fef4f4" ,"#96514d" ,"#e6b422" ,"#006e54" ,"#895b8a" ,"#fdeff2" ,"#8d6449" ,"#d9a62e" ,"#00a381" ,"#824880" ,"#e9dfe5" ,"#deb068" ,"#d3a243" ,"#38b48b" ,"#915c8b" ,"#e4d2d8" ,"#bf794e" ,"#c89932" ,"#00a497" ,"#9d5b8b" ,"#f6bfbc" ,"#bc763c" ,"#d0af4c" ,"#80aba9" ,"#7a4171" ,"#f5b1aa" ,"#b98c46" ,"#8b968d" ,"#5c9291" ,"#bc64a4" ,"#f5b199" ,"#b79b5b" ,"#6e7955" ,"#478384" ,"#b44c97" ,"#efab93" ,"#b77b57" ,"#767c6b" ,"#43676b" ,"#aa4c8f" ,"#f2a0a1" ,"#b68d4c" ,"#888e7e" ,"#80989b" ,"#cc7eb1" ,"#f0908d" ,"#ad7d4c" ,"#5a544b" ,"#2c4f54" ,"#cca6bf" ,"#ee827c" ,"#ad7d4c" ,"#56564b" ,"#1f3134" ,"#c4a3bf" ,"#f09199" ,"#ae7c4f" ,"#555647" ,"#47585c" ,"#e7e7eb" ,"#f4b3c2" ,"#ad7e4e" ,"#494a41" ,"#485859" ,"#dcd6d9" ,"#eebbcb" ,"#ae7c58" ,"#6b6f59" ,"#6c848d" ,"#d3cfd9" ,"#e8d3c7" ,"#a86f4c" ,"#474b42" ,"#53727d" ,"#d3ccd6" ,"#e8d3d1" ,"#946243" ,"#333631" ,"#5b7e91" ,"#c8c2c6" ,"#e6cde3" ,"#917347" ,"#5b6356" ,"#426579" ,"#a6a5c4" ,"#e5abbe" ,"#956f29" ,"#726250" ,"#4c6473" ,"#a69abd" ,"#e597b2" ,"#8c7042" ,"#9d896c" ,"#455765" ,"#a89dac" ,"#e198b4" ,"#7b6c3e" ,"#94846a" ,"#44617b" ,"#9790a4" ,"#e4ab9b" ,"#d8a373" ,"#897858" ,"#393f4c" ,"#9e8b8e" ,"#e09e87" ,"#cd8c5c" ,"#716246" ,"#393e4f" ,"#95859c" ,"#d69090" ,"#cd5e3c" ,"#cbb994" ,"#203744" ,"#95949a" ,"#d4acad" ,"#cb8347" ,"#d6c6af" ,"#4d4c61" ,"#71686c" ,"#c97586" ,"#c37854" ,"#bfa46f" ,"#eaf4fc" ,"#705b67" ,"#c099a0" ,"#c38743" ,"#9e9478" ,"#eaedf7" ,"#634950" ,"#b88884" ,"#c39143" ,"#a59564" ,"#e8ecef" ,"#5f414b" ,"#b48a76" ,"#bf783a" ,"#715c1f" ,"#ebf6f7" ,"#4f455c" ,"#a86965" ,"#bb5535" ,"#c7b370" ,"#c1e4e9" ,"#5a5359" ,"#a25768" ,"#bb5520" ,"#dcd3b2" ,"#bce2e8" ,"#594255" ,"#ec6d71" ,"#b55233" ,"#a19361" ,"#a2d7dd" ,"#524748" ,"#eb6ea5" ,"#aa4f37" ,"#8f8667" ,"#abced8" ,"#513743" ,"#e95295" ,"#9f563a" ,"#887938" ,"#a0d8ef" ,"#e6eae3" ,"#e7609e" ,"#9f563a" ,"#6a5d21" ,"#89c3eb" ,"#d4dcd6" ,"#d0576b" ,"#9a493f" ,"#918754" ,"#84a2d4" ,"#d4dcda" ,"#c85179" ,"#98623c" ,"#a69425" ,"#83ccd2" ,"#d3cbc6" ,"#e9546b" ,"#965042" ,"#ada250" ,"#84b9cb" ,"#c8c2be" ,"#e95464" ,"#965036" ,"#938b4b" ,"#698aab" ,"#b3ada0" ,"#c85554" ,"#95483f" ,"#8c8861" ,"#008899" ,"#a99e93" ,"#c53d43" ,"#954e2a" ,"#a1a46d" ,"#00a3af" ,"#a58f86" ,"#e83929" ,"#8f2e14" ,"#726d40" ,"#2a83a2" ,"#928178" ,"#e60033" ,"#8a3319" ,"#928c36" ,"#59b9c6" ,"#887f7a" ,"#e2041b" ,"#8a3b00" ,"#dccb18" ,"#2ca9e1" ,"#b4866b" ,"#d7003a" ,"#852e19" ,"#d7cf3a" ,"#38a1db" ,"#b28c6e" ,"#c9171e" ,"#7b4741" ,"#c5c56a" ,"#0095d9" ,"#a16d5d" ,"#d3381c" ,"#773c30" ,"#c3d825" ,"#0094c8" ,"#9f6f55" ,"#ce5242" ,"#783c1d" ,"#b8d200" ,"#2792c3" ,"#8c6450" ,"#d9333f" ,"#762f07" ,"#e0ebaf" ,"#007bbb" ,"#856859" ,"#b94047" ,"#752100" ,"#d8e698" ,"#5383c3" ,"#765c47" ,"#ba2636" ,"#6c3524" ,"#c7dc68" ,"#5a79ba" ,"#6f514c" ,"#b7282e" ,"#683f36" ,"#99ab4e" ,"#4c6cb3" ,"#6f4b3e" ,"#a73836" ,"#664032" ,"#7b8d42" ,"#3e62ad" ,"#544a47" ,"#9e3d3f" ,"#6d3c32" ,"#69821b" ,"#1e50a2" ,"#543f32" ,"#a22041" ,"#583822" ,"#aacf53" ,"#507ea4" ,"#554738" ,"#a22041" ,"#6c2c2f" ,"#b0ca71" ,"#19448e" ,"#433d3c" ,"#f8f4e6" ,"#640125" ,"#b9d08b" ,"#164a84" ,"#432f2f" ,"#ede4cd" ,"#f8b862" ,"#839b5c" ,"#165e83" ,"#3f312b" ,"#e9e4d4" ,"#f6ad49" ,"#cee4ae" ,"#274a78" ,"#302833" ,"#ebe1a9" ,"#f39800" ,"#82ae46" ,"#2a4073" ,"#ffffff" ,"#f2f2b0" ,"#f08300" ,"#a8c97f" ,"#223a70" ,"#fffffc" ,"#e4dc8a" ,"#ec6d51" ,"#9ba88d" ,"#192f60" ,"#f7fcfe" ,"#f8e58c" ,"#ee7948" ,"#c8d5bb" ,"#1c305c" ,"#f8fbf8" ,"#ddbb99" ,"#ed6d3d" ,"#c1d8ac" ,"#0f2350" ,"#fbfaf5" ,"#d7a98c" ,"#ec6800" ,"#a8bf93" ,"#17184b" ,"#f3f3f3" ,"#f2c9ac" ,"#ec6800" ,"#769164" ,"#0d0015" ,"#f3f3f2" ,"#fff1cf" ,"#ee7800" ,"#d6e9ca" ,"#bbc8e6" ,"#eae5e3" ,"#fddea5" ,"#eb6238" ,"#93ca76" ,"#bbbcde" ,"#e5e4e6" ,"#fce2c4" ,"#ea5506" ,"#93b881" ,"#8491c3" ,"#dcdddd" ,"#fde8d0" ,"#ea5506" ,"#badcad" ,"#8491c3" ,"#dddcd6" ,"#f9c89b" ,"#eb6101" ,"#97a791" ,"#4d5aaf" ,"#c0c6c9" ,"#f7bd8f" ,"#e49e61" ,"#98d98e" ,"#4d5aaf" ,"#afafb0" ,"#f6b894" ,"#e45e32" ,"#88cb7f" ,"#4a488e" ,"#adadad" ,"#f4dda5" ,"#e17b34" ,"#69b076" ,"#4d4398" ,"#a3a3a2" ,"#f1bf99" ,"#dd7a56" ,"#6b7b6e" ,"#5654a2" ,"#9ea1a3" ,"#f1bf99" ,"#db8449" ,"#bed2c3" ,"#706caa" ,"#9fa0a0" ,"#efcd9a" ,"#d66a35" ,"#93b69c" ,"#68699b" ,"#949495" ,"#efcd9a" ,"#ffd900" ,"#a6c8b2" ,"#867ba9" ,"#888084" ,"#f0cfa0" ,"#ffd900" ,"#47885e" ,"#dbd0e6" ,"#7d7d7d" ,"#edd3a1" ,"#ffea00" ,"#316745" ,"#a59aca" ,"#7b7c7d" ,"#e0c38c" ,"#ffec47" ,"#68be8d" ,"#7058a3" ,"#727171" ,"#f3bf88" ,"#fef263" ,"#3eb370" ,"#674598" ,"#595857" ,"#f7b977" ,"#fcd575" ,"#007b43" ,"#674196" ,"#595455" ,"#f19072" ,"#fbd26b" ,"#bed3ca" ,"#9079ad" ,"#524e4d" ,"#f19072" ,"#f5e56b" ,"#92b5a9" ,"#745399" ,"#474a4d" ,"#ee836f" ,"#eec362" ,"#7ebea5" ,"#65318e" ,"#383c3c" ,"#eb9b6f" ,"#ebd842" ,"#7ebeab" ,"#522f60" ,"#2b2b2b" ,"#e0815e" ,"#ffdb4f" ,"#028760" ,"#493759" ,"#2b2b2b" ,"#df7163" ,"#fbca4d" ,"#3b7960" ,"#2e2930" ,"#180614" ,"#d57c6b" ,"#fcc800" ,"#2f5d50" ,"#884898" ,"#281a14" ,"#d0826c" ,"#f8b500" ,"#3a5b52" ,"#c0a2c7" ,"#000b00" ,"#ca8269" ,"#fabf14" ,"#475950" ,"#460e44" ,"#250d00" ,"#bb5548" ,"#f7c114" ,"#00552e" ,"#74325c" ,"#241a08" ,"#ab6953" ,"#e6b422" ,"#005243" ,"#55295b" ,"#16160e"];

    let result = "";
    let resultR = 0;
    let resultG = 0;
    let resultB = 0;
    let point = 1000000;
    
    array.forEach(function(one){
      let r2 = parseInt(one.substring(1, 3), 16);
      let g2 = parseInt(one.substring(3, 5), 16);
      let b2 = parseInt(one.substring(5, 7), 16);
      let targetPoint = Math.abs(r - r2) + Math.abs(g - g2) + Math.abs(b - b2);
      if(targetPoint < point) {
        point = targetPoint;
        result = one;
        resultR = r2;
        resultG = g2;
        resultB = b2;
      }
    });
    ctx.fillStyle = "rgba(" + resultR + "," + resultG + "," + resultB + "," + a / 255 + ")";
    ctx.fillRect(i, j, 1, 1);
}
        const diff = canvas.width - i;
    	const widthPercentage = (i / canvas.width) * 100 / 2;
    	document.getElementById('Bar').style.width = widthPercentage + '%';
    if(i == canvas.width - 1) {
      MyThread2(ctx, canvas);
    }
}

async function MyThread2(ctx2, canvas2) {
  const canvas = document.getElementById('canvas2');
  const ctx = canvas.getContext('2d', { willReadFrequently: true });
  canvas.width = canvas2.width;
  canvas.height = canvas2.height;
  for(let i = 0; i < canvas2.width; i++) {
    for(let j = 0; j < canvas2.height; j++) {
      const imageData = ctx2.getImageData(i, j, 1, 1);
      ctx.fillStyle = "rgba(" + imageData.data[0] + "," + imageData.data[1] + "," + imageData.data[2] + "," + imageData.data[3] / 255 + ")";
      ctx.fillRect(i, j, 1, 1);
    }
  }
  let resultArrayR = [];
  let resultArrayG = [];
  let resultArrayB = [];
  let resultArrayA = [];
  for(let i = 0; i < canvas.width; i++) {
  for(let j = 0; j < canvas.height; j++) {
  let arrayR = [];
  let arrayG = [];
  let arrayB = [];
  resultArrayA.push(ctx.getImageData(i, j, 1, 1).data[3]);
  for(let i2 = i - 2; i2 <= i + 2; i2++) {
  for(let j2 = j - 2; j2 <= j + 2; j2++) {
    if(i2 < 0 || canvas.width <= i2 || j2 < 0 || canvas.height <= j2) continue;
    const imageData = ctx.getImageData(i2, j2, 1, 1);
    arrayR.push(imageData.data[0]);
    arrayG.push(imageData.data[1]);
    arrayB.push(imageData.data[2]);
  }
  }
  for(let i2 = 0; i2 < arrayR.length; i2++) {
  for(let j2 = i2 + 1; j2 < arrayR.length; j2++) {
    if(arrayR[i2] + arrayG[i2] + arrayB[i2] < arrayR[j2] + arrayG[j2] + arrayB[j2]) {
      let oneTimeR = arrayR[i2];
      let oneTimeG = arrayG[i2];
      let oneTimeB = arrayB[i2];
      arrayR[i2] = arrayR[j2];
      arrayG[i2] = arrayG[j2];
      arrayB[i2] = arrayB[j2];
      arrayR[j2] = oneTimeR;
      arrayG[j2] = oneTimeG;
      arrayB[j2] = oneTimeB;
    }
  }
  }
  //console.log(arrayR.length);
  if(arrayR.length == 25) {
    resultArrayR.push(arrayR[12]);
    resultArrayG.push(arrayG[12]);
    resultArrayB.push(arrayB[12]);
  }
  else {
    resultArrayR.push(arrayR[8]);
    resultArrayG.push(arrayG[8]);
    resultArrayB.push(arrayB[8]);
  }
  if(2 < i) {
  ctx.fillStyle = "rgba(" + resultArrayR[(i - 3) * canvas.height + j] + "," + resultArrayG[(i - 3) * canvas.height + j] + "," + resultArrayB[(i - 3) * canvas.height + j] + "," + resultArrayA[(i - 3) * canvas.height + j] / 255 + ")";
  ctx.fillRect(i - 3, j, 1, 1);

  if(i == canvas.width - 1) {
  ctx.fillStyle = "rgba(" + resultArrayR[(i - 2) * canvas.height + j] + "," + resultArrayG[(i - 2) * canvas.height + j] + "," + resultArrayB[(i - 2) * canvas.height + j] + "," + resultArrayA[(i - 2) * canvas.height + j] / 255 + ")";
  ctx.fillRect(i - 2, j, 1, 1);

    ctx.fillStyle = "rgba(" + resultArrayR[(i - 1) * canvas.height + j] + "," + resultArrayG[(i - 1) * canvas.height + j] + "," + resultArrayG[(i - 1) * canvas.height + j] + "," + resultArrayA[(i - 1) * canvas.height + j] / 255 + ")";
  ctx.fillRect(i - 1, j, 1, 1);

    ctx.fillStyle = "rgba(" + resultArrayR[i * canvas.height + j] + "," + resultArrayG[i * canvas.height + j] + "," + resultArrayB[i * canvas.height + j] + "," + resultArrayA[i * canvas.height + j] / 255 + ")";
  ctx.fillRect(i, j, 1, 1);
  }
  }
  }

  const widthPercentage = (i / canvas.width + 1) * 100 / 2;
  document.getElementById('Bar').style.width = widthPercentage + '%';
  const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
  await sleep(0);
  }
}

var file = document.querySelector('#getfile');

file.onchange = function (){
  var fileList = file.files;
  //読み込み
  var reader = new FileReader();
  reader.readAsDataURL(fileList[0]); 

  //読み込み後
  reader.onload = function  () {
    document.querySelector('#preview').src = reader.result;

    const canvas2 = document.getElementById('canvas2');
    canvas2.width = 0;
    canvas2.height = 0;

    const image = document.getElementById('preview');
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d', { willReadFrequently: true });
image.onload = function() {
    canvas.width = image.width;
    canvas.height = image.height;
    ctx.drawImage(image, 0, 0);
setTimeout(() => {
  for(let i = 0; i < canvas.width; i++) {
    setTimeout(() => {
      MyThread(i, ctx, canvas);
    }, 0);
  }
}, 0);
};
};
};


</script> 
</body>
</html>
```

***

以上、画像を和色のみの構成にする
html を公開しました。

作成中のイラストの
修正アイデアとして活用して頂けると
作成した側としても非常に嬉しいです。

皆さんの開発の助けになれますように。
閲覧ありがとうございました。