5种方式实现js图片主色调检测及更换背景色colorThief colorify Vibrant d

js实现图片主色调检测及更换背景色的5种方式colorThief colorify Vibrant daptive-backgrounds加原生

5种方式实现js图片主色调检测及更换背景色colorThief colorify Vibrant daptive-backgrounds加原生

开发中产品可能提这样的需求,网页幻灯片中背景色会根据当前图片的主色调进行动态更换,达到一定的美感,这个有点类似手机桌面主题根据手机壳颜色更换的那个需求(已经跟产品干起来了),今天不用跟产品吵起来,有5种实现方式呢。

一、colorThief

colorThief是一个非常有用且易于使用的插件,用于从图像中获取调色板。它的画布标签使它发生。如果使用已加载到DOM中的图像,则可以同步检索颜色调色板。

<script type="text/javascript">
    const colorThief = new ColorThief();
    const imgs = document.getElementById('imgs');

    // Make sure image is finished loading
    if (imgs.complete) {
        console.log(colorThief.getColor(imgs));
    } else {
        imgs.addEventListener('load', function() {
            let color = colorThief.getColor(imgs);
            var span = document.getElementById('span');
            span.style.background = "rgb(" +color[0] + "," + color[1]+ "," + color[2] + ")"
        });
    }
</script>

demo查看 http://editor.bfw.wiki/Editor/Open.html?projectid=15748222447089740088&file=demo1.html

二、colorify

使用 Colorify.js,,你可以:
从图像中提取主导颜色
根据图像的颜色生成渐变
隔离颜色并在页面中的任何地方操纵它们
为你的图像创建一个懒惰的revealer系统
动态加载图像

<script type="text/javascript">
    const imgs = document.getElementById('imgs');

    // Make sure image is finished loading
    if (imgs.complete) {
        console.log(colorThief.getColor(imgs));
    } else {
        imgs.addEventListener('load', function() {
            colorify({
                id: 1,
                container: 'colorify',
                images: false,
                accuracy: 100,
                gradient: false,
                gradientDirection: false,
                padding: 10,
                lazyReveal: false,
                give: false,
                revealOn: false
            });

            var span = document.getElementById('span');
            span.style.background = "rgb(" +color[0] + "," + color[1]+ "," + color[2] + ")"
        });
    }
</script>

demo查看 http://editor.bfw.wiki/Editor/Open.html?projectid=15748222447089740088&file=demo2.html

三、Vibrant

Vibrant是一个从图像中提取突出颜色的实用程序,Vibrant是Android支持库中awesome Palette类的一个javascript端口。

<script type="text/javascript">

    img.addEventListener('load', function() {
        var vibrant = new Vibrant(img);
        var swatches = vibrant.swatches()
        for (var swatch in swatches)
            if (swatches.hasOwnProperty(swatch) && swatches[swatch])
            document.getElementById('span'+swatch).style.background = swatches[swatch].getHex();
        console.log(swatch, swatches[swatch].getHex())

        /*
     * Results into:
     * Vibrant #7a4426
     * Muted #7b9eae
     * DarkVibrant #348945
     * DarkMuted #141414
     * LightVibrant #f3ccb4
     */
    });
</script>

查看demo http://editor.bfw.wiki/Editor/Open.html?projectid=15748222447089740088&file=demo3.html


四、adaptive-backgrounds

adaptive-background.js是一款jQuery插件,可以根据div,img标签里图片的边框颜色来动态调整父标签的背景颜色,有点类似iTunes的专辑详情的效果.

$(document).ready(function() {
  $.adaptiveBackground.run()
});

demo查看 http://editor.bfw.wiki/Editor/Open.html?projectid=15748222447089740088


五、自己实现

自己实现的过程就是:

1、数据获取
图片数据获取使用了canvas的getImageData()方法,能获取到图片每个像素点的rgba数据。
2、数据聚类
去重,相同色值合并,记录该色值出现个数(权重)weight
聚类方法就比较多了,直接数学统计,或者k-means,决策树,朴素贝叶斯,支持向量机等等,喜欢哪个就用哪个就可以了,但是还是需要考虑下不同方法的适用情况和效率什么的了。
我们会得到这样一个数组 [{rgba: '21,12,45,0', weight: 12}, {...}]来记录色值和出现次数,
3、聚类结果排序
对上一步中得到的json数组进行排序,根据属性weight的值从大到小或者从小到大排序,排序算法就不用多言了。

看代码

<script type="text/javascript">
    function getAverageRGB(imgEl) {

        var blockSize = 5,
        // only visit every 5 pixels
        defaultRGB = {
            r: 0,
            g: 0,
            b: 0
        },
        // for non-supporting envs
        canvas = document.createElement('canvas'),
        context = canvas.getContext && canvas.getContext('2d'),
        data,
        width,
        height,
        i = -4,
        length,
        rgb = {
            r: 0,
            g: 0,
            b: 0
        },
        count = 0;

        if (!context) {
            return defaultRGB;
        }

        height = canvas.height = imgEl.naturalHeight || imgEl.offsetHeight || imgEl.height;
        width = canvas.width = imgEl.naturalWidth || imgEl.offsetWidth || imgEl.width;

        context.drawImage(imgEl, 0, 0);

        try {
            data = context.getImageData(0, 0, width, height);
        } catch(e) {
            /* security error, img on diff domain */
            alert('x');
            return defaultRGB;
        }

        length = data.data.length;

        while ((i += blockSize * 4) < length) {
            ++count;
            rgb.r += data.data[i];
            rgb.g += data.data[i+1];
            rgb.b += data.data[i+2];
        }

        // ~~ used to floor values
        rgb.r = ~~(rgb.r/count);
        rgb.g = ~~(rgb.g/count);
        rgb.b = ~~(rgb.b/count);

        return rgb;

    }
</script>
demo查看 http://editor.bfw.wiki/Editor/Open.html?projectid=15748222447089740088&file=demo4.html


{{collectdata}}

网友评论0