javascript HTML5 Canvas:更改图像颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24405245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML5 Canvas: Change Image Color
提问by Mohit Pandey
I have an image(in greyscale form) of which i want to change the color(user specific). Since its quite difficult to change the color of a greyscale image, i come with an approach.
我有一个图像(灰度形式),我想更改其颜色(特定于用户)。由于更改灰度图像的颜色非常困难,因此我提出了一种方法。
Image is divided into two parts.
图像分为两部分。
- One is the image with white color.
- Second, a semi transparent image with grayscale.
- 一种是白色的图像。
- 其次,具有灰度的半透明图像。
Now, i place both image on top of each other(with white image on below and greyscale image on top) such that when i change the color of white image, it will be visible to user.
现在,我将两个图像放在一起(下面是白色图像,顶部是灰度图像),这样当我更改白色图像的颜色时,用户就可以看到它。
Problem: This approach works for me, except one issue. When i color the white image, it will pixellete from corners.
问题:这种方法对我有用,除了一个问题。当我给白色图像上色时,它会从角落开始像素化。
JSFiddle: http://jsfiddle.net/pandey_mohit/BeSwL/
JSFiddle:http: //jsfiddle.net/pandey_mohit/BeSwL/
JSFiddle contains three images for capsules:
JSFiddle 包含三个胶囊图像:
- Top Capsule Part White Image (for coloring)
- Bottom Capsule Part White Image (for coloring)
- Semi Transparent Image for 3D effect (using grayscale)
- 顶部胶囊部分白色图像(用于着色)
- 底部胶囊部分白色图像(用于着色)
- 用于 3D 效果的半透明图像(使用灰度)
Select red, green or blue color to see the issue.
选择红色、绿色或蓝色以查看问题。
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);
}
回答by Philipp
Your recoloring algorithm sets the 4th byte of each RGBA quartet to 255, which discards the alpha channel of the overlay and breaks the anti-aliasing around the edges of the image. Keeping the alpha channel of the original gives you better results:
您的重新着色算法将每个 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;
}