HTML5画布:更改图像颜色

7
我有一张灰度图像,我想要更改其颜色(用户指定)。由于更改灰度图像的颜色相当困难,所以我提出了一种方法。将图像分成两个部分:
1. 白色图像。 2. 半透明的灰度图像。
现在,我将这两个图像叠放在彼此上面(白色图像在下面,灰度图像在上面),这样当我更改白色图像的颜色时,用户就可以看到它。问题是:这种方法对我有效,但存在一个问题。当我给白色图像上色时,会从角落处产生像素点。
JSFiddle: http://jsfiddle.net/pandey_mohit/BeSwL/ JSFiddle 包含三个胶囊的图像:
1. 顶部胶囊部分的白色图像(用于着色)。 2. 底部胶囊部分的白色图像(用于着色)。 3. 半透明图像,用于 3D 效果(使用灰度)。
选择红色、绿色或蓝色以查看问题。
function hexToRgb(color) {
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    color = color.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : {
        r: 0,
        g: 0,
        b: 0
    };
}

function colorImage(imgId,hexaColor) {
    // create hidden canvas (using image dimensions)
    var imgElement = document.getElementById(imgId);

    var canvas = document.createElement("canvas");
    canvas.width = imgElement.width;
    canvas.height = imgElement.height;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(imgElement,0,0);

    var imageData = ctx.getImageData(0,0,canvas.width,canvas.height);

    var data = imageData.data;

    // convert image to grayscale
    var rgbColor = hexToRgb(hexaColor);

    for(var p = 0, len = data.length; p < len; p+=4) {
        if(data[p+3] == 0)
           continue;
        data[p + 0] = rgbColor.r;
        data[p + 1] = rgbColor.g;
        data[p + 2] = rgbColor.b;
        data[p + 3] = 255;
    }
    ctx.putImageData(imageData, 0, 0);

    // replace image source with canvas data
    imgElement.src = canvas.toDataURL();
}

// changing color of capsule on select event
document.getElementById('sel_top').onchange = function(){
    colorImage('img_top', this.value);
}
document.getElementById('sel_bottom').onchange = function(){
    colorImage('img_bottom', this.value);
}
1个回答

9
您的重新着色算法将每个RGBA四元组的第4个字节设置为255,这会丢弃覆盖层的Alpha通道并破坏图像边缘周围的反锯齿效果。保留原始图像的Alpha通道可以获得更好的结果。
for(var p = 0, len = data.length; p < len; p+=4) {
    data[p + 0] = rgbColor.r;
    data[p + 1] = rgbColor.g;
    data[p + 2] = rgbColor.b;
}

注释掉的代码行的JSFiddle链接


你能用这个处理不同的图片吗? - MisterJuanXDLOL
1
@MisterJuanXDLOL 如果您在将此技术应用于多个图像时遇到特定问题,请随时提出新问题。 - Philipp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接