语言:js
颜色量化算法:中位切分法
简介
1.获取图像的像素点数据,getImageData,得到的数据每四位分别代表一个rgba的值,这里可以把透明的像素点去掉即a=0的像素点,也可以把范围设置大一点。按每四位存到一个数组里头,接下来就是对数组进行处理。
2.中位切分算法首先把所有像素映射到RGB空间,我们以R,G,B中最长的边构造一个立方体,并且以这条边从中间切割,可以分别得到两个包含相同像素点的长方体,再以长方体的最长边进行中位切割,如此反复下去,满足条件时停止切割,比如颜色的极值小于50停止,或者长方体少于100个像素点时停止,此时,我们得到了满足条件的长方体,把像素点的平均值作为了此长方体的代表颜色。
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>getcolor</title>
</head>
<body>
<img src="12.png" alt="" id="myimage">
<canvas id="mycanvas"></canvas>
<div id="imagecolor" style="display: flex;width: 100%;"></div>
</body>
<script>
var qulity=100,count=0;
window.onload = function () {
var img=document.getElementById("myimage");
var image=new Image();
image.src=img.src;
var canvas=document.getElementById("mycanvas");
var ctx = canvas.getContext('2d');
ctx.drawImage(img,0,0,image.width,image.height,0,0,300,150);
var data = ctx.getImageData(0, 0,image.width,image.height).data;//读取整张图片的像素。
var rgbArray=new Array();
for(var i=0;i<data.length;i+=4){
var rdata=data[i]; //240-250
var gdata=data[i+1]; //70-100
var bdata=data[i+2];//80-120
var adata=data[i+3];
if(adata>125){
rgbArray.push([rdata,gdata,bdata,adata]);
}
}
console.log(rgbArray);
GetColor(rgbArray);
console.log(count);
}
//获取主题色
function GetColor(cube){
var maxr=cube[0][0],minr=cube[0][0],maxg=cube[0][1],ming=cube[0][1],maxb=cube[0][2],minb=cube[0][2];
for(var i=0;i<cube.length;i++)
{
if(cube[i][0]>maxr){
maxr=cube[i][0];
}
if(cube[i][0]<minr){
minr=cube[i][0];
}
if(cube[i][1]>maxg){
maxg=cube[i][1];
}
if(cube[i][1]<ming){
ming=cube[i][1];
}
if(cube[i][2]>maxb){
maxb=cube[i][2];
}
if(cube[i][2]<minb){
minb=cube[i][2];
}
}
if((maxr-minr)<qulity&&(maxg-ming)<qulity&&(maxb-minb)<qulity){
var r=0,g=0,b=0;
for(var i=0;i<cube.length;i++){
r+=cube[i][0];
g+=cube[i][1];
b+=cube[i][2];
}
var divcolor=document.createElement("div");
divcolor.style.backgroundColor="rgba("+r/(cube.length)+","+g/(cube.length)+","+b/(cube.length)+")";
divcolor.style.width="100px";
divcolor.style.height="100px";
var html=document.getElementById("imagecolor");
html.appendChild(divcolor);
}else{
var maxrgb=0;
var rgbindex=0;
var rgbmiddle=0;
if((maxr-minr)>maxrgb)
{
maxrgb=(maxr-minr);
rgbmiddle=(maxr+minr)/2
rgbindex=0;
}
if((maxg-ming)>maxrgb)
{
maxrgb=(maxg-ming);
rgbmiddle=(maxg+ming)/2;
rgbindex=1;
}
if((maxb-minb)>maxrgb)
{
maxrgb=(maxb-minb);
rgbmiddle=(maxb+minb)/2;
rgbindex=2;
}
//排序
cube.sort(function(x,y){
return x[rgbindex]-y[rgbindex];
});
var cubea=new Array();
var cubeb=new Array();
for(var i=0;i<cube.length;i++){
if(cube[i][rgbindex]<rgbmiddle){
cubea.push(cube[i]);
}else{
cubeb.push(cube[i]);
}
}
GetColor(cubeb);
GetColor(cubea);
}
}
</script>
</html>
网友评论