22 votes

Est-il possible de remplacer une couleur dans une image codée en base 64 ?

Existe-t-il un moyen de prendre une chaîne en base 64, par exemple :

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

Et remplacer une couleur unie par une autre couleur unie en utilisant JavaScript ?

Dans cet exemple précis, j'ai utilisé une couleur unie dans l'icône ( #13A3F7 ) que j'aimerais remplacer par une autre couleur unie ( #ff6400 ).

La raison en est qu'il ne s'agit pas d'un cas unique. J'aimerais pouvoir changer l'icône en tous couleur avec un réglage.

Y a-t-il un moyen de le faire ?

26voto

lostsource Points 6182

Voici une petite fonction qui prend 3 paramètres : data, colorFrom, colorTo (les deux couleurs doivent être fournies en hexadécimal)

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();
}

Une fonction supplémentaire est nécessaire pour convertir les couleurs hexagonales en couleurs RVB (pour une correspondance correcte).

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;
}

L'utilisation serait la suivante :

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

Il renverra un nouvel URI data:image/png ; avec les couleurs échangées. Voici un exemple de résultat final.

http://jsfiddle.net/V5dU2/

(testé sur Chrome, Firefox et IE10)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X