【问题标题】:Is it possible to replace a color in a base 64-encoded image?是否可以替换 base 64 编码图像中的颜色?
【发布时间】:2012-11-16 23:32:17
【问题描述】:

有没有办法取base 64的字符串,例如:

.copyIcon {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAW0lEQVR42mNgQALCi7//J4QZcAFiNOM1hJANBA0h1QC83iHFizDJ/dgww/7/LAQNwKUZbkjDfya8YQZXiCqJagilBmAzhLYGYDNsJBhAMD3gS854NS/6vg+fZgDKvmW19S7PRAAAAABJRU5ErkJggg==") center center no-repeat;}

并使用 JavaScript 将纯色替换为另一种纯色?

在这个具体示例中,我想用另一种纯色 (#ff6400) 替换图标中的纯色 (#13A3F7)。

这样做的原因是它不是一次性的。我希望能够通过设置将图标更改为任何颜色。

有什么办法可以做到吗?

【问题讨论】:

    标签: javascript css base64


    【解决方案1】:

    这是一个小函数,它接受 3 个参数:data、colorFrom、colorTo(两种颜色都应以十六进制提供)

    function changeColInUri(data,colfrom,colto) {
        // create fake image to calculate height / width
        var img = document.createElement("img");
        img.src = data;
        img.style.visibility = "hidden";
        document.body.appendChild(img);
    
        var canvas = document.createElement("canvas");
        canvas.width = img.offsetWidth;
        canvas.height = img.offsetHeight;
    
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img,0,0);
    
        // remove image
        img.parentNode.removeChild(img);
    
        // do actual color replacement
        var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);
        var data = imageData.data;
    
        var rgbfrom = hexToRGB(colfrom);
        var rgbto = hexToRGB(colto);
    
        var r,g,b;
        for(var x = 0, len = data.length; x < len; x+=4) {
            r = data[x];
            g = data[x+1];
            b = data[x+2];
    
            if((r == rgbfrom.r) &&
               (g == rgbfrom.g) &&
               (b == rgbfrom.b)) {
    
                data[x] = rgbto.r;
                data[x+1] = rgbto.g;
                data[x+2] = rgbto.b;
    
            } 
        }
    
        ctx.putImageData(imageData,0,0);
    
        return canvas.toDataURL();
    }
    

    需要一个额外的函数将十六进制颜色转换为 RGB(正确匹配)

    function hexToRGB(hexStr) {
        var col = {};
        col.r = parseInt(hexStr.substr(1,2),16);
        col.g = parseInt(hexStr.substr(3,2),16);
        col.b = parseInt(hexStr.substr(5,2),16);
        return col;
    }
    

    用法如下:

    changeColInUri(
        "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAW0lEQVR42mNgQALCi7//J4QZcAFiNOM1hJANBA0h1QC83iHFizDJ/dgww/7/LAQNwKUZbkjDfya8YQZXiCqJagilBmAzhLYGYDNsJBhAMD3gS854NS/6vg+fZgDKvmW19S7PRAAAAABJRU5ErkJggg==",
        "#13A3F7",
        "#ff6400"
    );
    

    它会返回一个新的数据:image/png;带有交换颜色的 URI,这是最终结果的工作 jsfiddle

    http://jsfiddle.net/V5dU2/

    (在 Chrome、Firefox 和 IE10 上测试)

    【讨论】:

    • 伟大的想法。请注意,它确实需要 &lt;canvas&gt; 支持,而 IE 8 及更早版本本身不具备此功能。
    • @PaulD.Waite 恕我直言,因为 IE 8 甚至不能很好地处理数据 URI(最大长度为 32KB),这应该不是问题。
    • 从我在 caniuse.com 上读到的内容来看,IE 问题(如您所说,取决于大小)是 HTML 中的数据 URI,而不是 CSS 中的……如果有帮助的话。
    • 您好,很好的答案和脚本。实施它。但是,在第一次加载时,它似乎总是输出一个透明的 png。在用户交互中使用脚本时,它似乎工作正常。有人遇到过这个问题吗?
    • DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The source width is 0
    猜你喜欢
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    • 2019-02-16
    • 2015-05-15
    • 2017-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多