「画像ファイルの色を置換したい」を改良する(1)のブラウザ版をつくります。デスクトップアプリをつくって公開してもいまではほとんどダウンロードしてくれません。webアプリならurlを伝えるだけで来てもらえるようになります。
Contents
HTML部分
まずHTML部分を示します。アップロードボタンをクリックしたら画像を表示し、クリックで色情報を取得して置換前と置換後の色を選択できるようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>ブラウザで画像ファイルの色を置換する</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="./style.css" type="text/css" media="all"> </head> <body> <div id = "clicked-color"></div> <div id = "before-color-outer"> <button onclick="ClearBeforeColor()">クリア</button> <button onclick="SaveBeforeColor()">記憶</button> <span id = "before-color"></span> </div> <div id = "after-color-outer"> <button onclick="ClearAfterColor()">クリア</button> <button onclick="SaveAfterColor()">記憶</button> <span id = "after-color"></span> </div> <div> <canvas id="canvas"></canvas> </div> <div> <input id="fileupload" type="file" name="fileupload" accept="image/*"> <button class = "button1" id="upload-button" onclick="UploadFile()">アップロードする</button> </div> <div> <button class = "button2" onclick="ReplaseColor()">置換</button> </div> <div> <button class = "button2" onclick="Download()">ダウンロード</button> </div> <script src="./app.js"></script> </body> </html> |
style.cssを示します。見た目を整えているだけです。
style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#clicked-color { border: 1px solid #ccc; margin-bottom: 10px; width: 480px; padding: 5px; } #before-color-outer { border: 1px solid #ccc; margin-bottom: 10px; width: 480px; padding: 5px; } #after-color-outer { border: 1px solid #ccc; margin-bottom: 10px; width: 480px; padding: 5px; } .button1 { width: 150px; margin-bottom: 10px; } .button2 { width: 100px; margin-bottom: 10px; } |
JavaScript部分
JavaScript部分を示します。最初にグローバル変数を示します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// canvas let $canvas = document.getElementById("canvas"); // 2Dコンテキスト let $ctx = $canvas.getContext("2d"); // 画像の取得。 let $image = document.createElement('img'); let $clickedColor = document.getElementById('clicked-color'); let $beforeColor = document.getElementById('before-color'); let $beforeColorOuter = document.getElementById('before-color-outer'); let $afterColor = document.getElementById('after-color'); let $afterColorOuter = document.getElementById('after-color-outer'); |
クリックされた座標の色、置換前の色、置換後の色を保存するためのグローバル変数として以下を定義します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
let clickedColor = { r : 0, g : 0, b : 0, a : 0, }; let beforeColor = { r : 0, g : 0, b : 0, a : 0, }; let afterColor = { r : 0, g : 0, b : 0, a : 0, }; |
初期化
ページが読み込まれたらクリックされた色を初期化します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
window.onload = () => { SetClickedColor(); } function SetClickedColor(color){ let characterColor = ''; if(color != undefined){ clickedColor.r = color.r; clickedColor.g = color.g; clickedColor.b = color.b; clickedColor.a = color.a; characterColor = (clickedColor.r + clickedColor.g + clickedColor.b) / 3 > 128 ? '#000' : '#fff'; } else { clickedColor.r = 255; clickedColor.g = 255; clickedColor.b = 255; clickedColor.a = 255; characterColor = '#000'; } if(clickedColor.a == 0) characterColor = '#000'; if($clickedColor) { let rgba = `rgba(${clickedColor.r}, ${clickedColor.g}, ${clickedColor.b}, ${clickedColor.a})`; $clickedColor.style.backgroundColor = rgba; $clickedColor.style.color = characterColor; $clickedColor.innerText = 'クリックされた座標の色 ' + rgba; } } |
画像ファイルをアップロードする
アップロードボタンをクリックしたときの処理を示します。画像ファイルを読み込んでcanvas要素内に表示します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function UploadFile(){ let fileupload = document.getElementById('fileupload'); let file = fileupload.files[0]; const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = (e) => { $image.src = e.target.result; $image.onload = () => { let width = $image.width; let height = $image.height; // canvasのサイズを画像サイズと同じにする $canvas.width = width; $canvas.height = height; // canvasに画像を描画する $ctx.drawImage($image, 0, 0); } }; } |
クリック時の処理
canvasがクリックされたらどの部分がクリックされたか調べてその色情報を保存します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
canvas.onclick = function(ev) { let color = GetColor(ev); SetClickedColor(color); } function GetColor(ev){ // マウス座標の取得。 var x = parseInt(ev.offsetX); var y = parseInt(ev.offsetY); // 指定座標のImageDataオブジェクトの取得。 var imagedata = $ctx.getImageData(x, y, 1, 1); var r = imagedata.data[0]; var g = imagedata.data[1]; var b = imagedata.data[2]; var a = imagedata.data[3]; let color = { r : r, g : g, b : b, a : a, } return color; } |
色情報の一次保存とクリア
保存ボタンがクリックされたらclickedColorに格納されている情報をbeforeColorまたはafterColorに保存するとともに視覚的にもわかるように該当要素の背景色と表示されている文字列を変更します。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
function SaveBeforeColor(){ beforeColor = { r : clickedColor.r, g : clickedColor.g, b : clickedColor.b, a : clickedColor.a, }; if($beforeColor) { let rgba = `rgba(${beforeColor.r}, ${beforeColor.g}, ${beforeColor.b}, ${beforeColor.a})`; let characterColor = (beforeColor.r + beforeColor.g + beforeColor.b) / 3 > 128 ? '#000' : '#fff'; if(beforeColor.a == 0) characterColor = '#000'; $beforeColorOuter.style.backgroundColor = rgba; $beforeColor.style.color = characterColor; $beforeColor.innerText = ' ' + rgba; } } function SaveAfterColor(){ afterColor = { r : clickedColor.r, g : clickedColor.g, b : clickedColor.b, a : clickedColor.a, }; if($afterColor) { let rgba = `rgba(${afterColor.r}, ${afterColor.g}, ${afterColor.b}, ${afterColor.a})`; let characterColor = (afterColor.r + afterColor.g + afterColor.b) / 3 > 128 ? '#000' : '#fff'; if(afterColor.a == 0) characterColor = '#000'; if($afterColorOuter) $afterColorOuter.style.backgroundColor = rgba; $afterColor.style.color = characterColor; $afterColor.innerText = ' ' + rgba; } } |
クリアボタンがクリックされたら保存されている色情報をクリアします。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
function ClearBeforeColor(){ beforeColor = { r : 0, g : 0, b : 0, a : 0, }; if($beforeColor) { if($beforeColorOuter) $beforeColorOuter.style.backgroundColor = 'rgba(0, 0, 0, 0)'; $beforeColor.style.color = '#000'; $beforeColor.innerText = ' ' + 'rgba(0, 0, 0, 0)'; } } function ClearAfterColor(){ afterColor = { r : 0, g : 0, b : 0, a : 0, }; if($afterColor) { if($afterColorOuter) $afterColorOuter.style.backgroundColor = 'rgba(0, 0, 0, 0)'; $afterColor.style.color = '#000'; $afterColor.innerText = ' ' + 'rgba(0, 0, 0, 0)'; } } |
canvas要素に表示されている画像の色を置換する
置換ボタンがクリックされたらcanvas要素に表示されている画像の各ピクセルを調べて置換すべき色を置き換えます。そして置換された画像を表示させます。
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function ReplaseColor(){ var imagedata = $ctx.getImageData(0, 0, $canvas.width, $canvas.height); for (var i = 0; i < imagedata.width * imagedata.height * 4; i += 4) { if( imagedata.data[i + 0] == beforeColor.r && imagedata.data[i + 1] == beforeColor.g && imagedata.data[i + 2] == beforeColor.b && imagedata.data[i + 3] == beforeColor.a) { imagedata.data[i + 0] = afterColor.r; imagedata.data[i + 1] = afterColor.g; imagedata.data[i + 2] = afterColor.b; imagedata.data[i + 3] = afterColor.a; } } $ctx.putImageData(imagedata, 0, 0); } |
canvasに表示されている画像を保存する
ダウンロードボタンがクリックされたらcanvasに表示されている画像をダウンロードして保存します。
app.js
1 2 3 4 5 6 |
function Download(){ const a = document.createElement("a"); a.href = $canvas.toDataURL("image/png"); a.download = "image.png"; a.click(); } |