语言: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>

参考资料

图像颜色提取
https://segmentfault.com/a/1190000009832996