<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>canvasで色の平均を取得</title>
<style>
/*表示確認用CSS*/
main {
display: flex;
}
main > div {
position: relative;
width: 320px;
margin-right: 20px;
background-color: #EEE;
}
h2 {
position: absolute;
width: 320px;
margin-top: 330px;
text-align: center;
}
img {
vertical-align: bottom;
}
#canvas,
#color {
position: absolute;
top: 93px;
left: 93px;
}
#color {
width: 134px;
height: 134px;
line-height: 134px;
border-radius: 50%;
color: #FFF;
text-align: center;
}
</style>
</head>
<body>
<h1>canvasで色の平均を取得</h1>
<main>
<div>
<h2>元画像</h2>
<img id="img" src="img/ball.jpg" alt="" width="320" height="320">
</div>
<div>
<h2>canvas転写</h2>
<canvas id="canvas" width="134" height="134"></canvas>
</div>
<div>
<h2>色の平均</h2>
<div id="color"></div>
</div>
</main>
<script>
window.onload = () =>{
const img = document.getElementById("img");
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d');
const color = document.getElementById("color");
/* canvasのサイズと位置取得 */
const canvasW = canvas.width;
const canvasH = canvas.height;
const canvasX = canvas.offsetTop;
const canvasY = canvas.offsetLeft;
/* 円で切り抜き */
ctx.beginPath();
ctx.arc(canvasW / 2, canvasH / 2, Math.round(canvasW / 2), 0, Math.PI*2, false);
ctx.clip();
/* 元画像の指定部分をcanvasに転写 */
ctx.drawImage(img, //元画像
canvasX, canvasY, canvasW, canvasH, //元画像の切り抜き範囲
0, 0, canvasW, canvasH //canvas転写範囲(全体)
);
/* 色の平均取得 */
const getAverageColor = () => {
const data = ctx.getImageData(0, 0, canvasW, canvasH).data;
let averageColor = {r:0, g:0, b:0};
let n = 0;
/* canvasの左上から[r,g,b,a]の配列を調査 */
for(let i = 0, len = data.length; i < len; i += 4) {
if(data[i + 3] === 255){//不透明色のみ取得
averageColor.r += data[i];
averageColor.g += data[i + 1];
averageColor.b += data[i + 2];
n++;
}
}
/* RGBの平均計算 */
averageColor.r = Math.round(averageColor.r / n);
averageColor.g = Math.round(averageColor.g / n);
averageColor.b = Math.round(averageColor.b / n);
return averageColor;
};
/* 色の平均書き出し */
let average = getAverageColor();
color.style.backgroundColor = `rgb(${average.r},${average.g},${average.b})`;
color.innerText = `rgb(${average.r},${average.g},${average.b})`;
};
</script>
</body>
</html>