Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布-使用HTML5/CSS/JS更改图像的颜色?_Javascript_Css_Html_Canvas_Html5 Canvas - Fatal编程技术网

Javascript 画布-使用HTML5/CSS/JS更改图像的颜色?

Javascript 画布-使用HTML5/CSS/JS更改图像的颜色?,javascript,css,html,canvas,html5-canvas,Javascript,Css,Html,Canvas,Html5 Canvas,有没有办法只使用HTML5/CSS/JavaScript就可以像Flash/ActionScript那样改变图像的颜色 下面是Flash中的一个示例:编辑:这是我希望复制的过程。 我正在尝试完成这样的事情(颜色变化方面,保留灯光和阴影):无需每次加载和替换新图像;我希望能够简单地更改色调(即,使用纯HTML5/CSS/JS方法)编辑:这是我希望实现的结果,而不是过程。 基本上,我想改变图像的调色板/色调,同时保留图像的其他方面(如渐变、照明等)。我已经接近了,但还不够接近;我已经到了使用图像遮罩

有没有办法只使用HTML5/CSS/JavaScript就可以像Flash/ActionScript那样改变图像的颜色

下面是Flash中的一个示例:编辑:这是我希望复制的过程。

我正在尝试完成这样的事情(颜色变化方面,保留灯光和阴影):无需每次加载和替换新图像;我希望能够简单地更改色调(即,使用纯HTML5/CSS/JS方法)编辑:这是我希望实现的结果,而不是过程。

基本上,我想改变图像的调色板/色调,同时保留图像的其他方面(如渐变、照明等)。我已经接近了,但还不够接近;我已经到了使用图像遮罩并在原始图像上合成的地步(有点像透明图像叠加)。下面是一些示例代码(请注意,这只是一个片段,所以它可能会工作,也可能不会工作;我只显示示例代码,以便您了解我尝试执行的操作):


红色
绿色
foo={};
foo.ctx=jQuery('#canvas')[0];
foo.ctx_context=foo.ctx.getContext('2d');
foo.mask=jQuery('#mask')[0];
foo.img=新图像();
foo.img_path='/path/to/image_mask.png';//100px 100px图像
foo.changeColor=函数(rgba){
ctx_context.clearRect(0,01001100);
foo.ctx_context.fillStyle='rgba('+rgba+');
foo.ctx_context.fillRect(0,01001100);
foo.ctx_context.globalCompositeOperation='destination-top';
ctx_context.drawImage(foo.img,0,0);
css({'background-image':“url”(+foo.ctx.toDataURL(“image/png”)+”)));
};
jQuery(“按钮”)。单击(函数(){
changeColor(jQuery(this.attr('data-rgba'));
});

使用这种方法的主要问题是图像看起来非常平坦。还有一些东西不见了,或者我使用的遮罩(一个纯白不规则形状的图像)是错误的方法。

通常在服务器端做一些像逐像素更改图像这样的事情,因为这对浏览器来说非常沉重。在Acura网站的情况下,没有什么棘手的事情发生-他们只是有一堆不同的JPG。您还可以尝试查看Processing.js。

当然,您可以获取像素数据,并对其进行HSV调整。您需要的方法是getImageData(它返回一个UInt8Array,而不是一个普通的js数组)


有一本好书应该能让你开始。您可以将透明画布元素层叠在一起,这将有助于避免调整基础组件(在您的汽车示例中,轮胎、车窗等)时出现问题

此函数要求加载映像,并且必须来自同一域(由于跨域策略)


这里的工作示例:

我没有逐像素绘制任何东西;我在现有图像上合成图像遮罩,这比每次查询后端以进行颜色更改要快得多。Acura所做的是我想要达到的结果,而不是过程。Flash可以很好地改变颜色/色调(这是即时的),但不幸的是,你不能在iPad上使用Flash,这就是为什么我在寻找HTML5解决方案的原因。一旦你有了答案,请发布一份完整的提琴。谢谢请注意,当你说跨域时,使用chrome在本地开发的人将看不到这一点(我总是在本地直通web服务器上运行以验证它是否有效)。我喜欢你的方法,但发现它重写了所有alpha通道。。。所以我添加了一个alphas数组,然后将它们写回。效果很好。代码位于:
<div id='mask'>
    <canvas id='canvas' width='100' height='100'></canvas>
</div>
<button data-rgba='255,0,0,0.5'>red</button>
<button data-rgba='0,255,0,0.5'>green</button>

<script>
foo = {};
foo.ctx = jQuery('#canvas')[0];
foo.ctx_context = foo.ctx.getContext('2d');
foo.mask = jQuery('#mask')[0];
foo.img = new Image();
foo.img_path = '/path/to/image_mask.png'; // 100px x 100px image

foo.changeColor = function(rgba){
    foo.ctx_context.clearRect(0, 0, 100, 100);
    foo.ctx_context.fillStyle = 'rgba(' + rgba + ')';
    foo.ctx_context.fillRect(0, 0, 100, 100);
    foo.ctx_context.globalCompositeOperation = 'destination-atop';
    foo.ctx_context.drawImage(foo.img, 0, 0);
    foo.ctx_context.css({'background-image': "url(" + foo.ctx.toDataURL("image/png") + ")"});
};

jQuery("button").click(function(){
    foo.changeColor(jQuery(this).attr('data-rgba'));
});
</script>
function tintImage(imgElement,tintColor) {
    // create hidden canvas (using image dimensions)
    var canvas = document.createElement("canvas");
    canvas.width = imgElement.offsetWidth;
    canvas.height = imgElement.offsetHeight;

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

    var map = ctx.getImageData(0,0,320,240);
    var imdata = map.data;

    // convert image to grayscale
    var r,g,b,avg;
    for(var p = 0, len = imdata.length; p < len; p+=4) {
        r = imdata[p]
        g = imdata[p+1];
        b = imdata[p+2];
        // alpha channel (p+3) is ignored           

        avg = Math.floor((r+g+b)/3);

        imdata[p] = imdata[p+1] = imdata[p+2] = avg;
    }

    ctx.putImageData(map,0,0);

    // overlay filled rectangle using lighter composition
    ctx.globalCompositeOperation = "lighter";
    ctx.globalAlpha = 0.5;
    ctx.fillStyle=tintColor;
    ctx.fillRect(0,0,canvas.width,canvas.height);

    // replace image source with canvas data
    imgElement.src = canvas.toDataURL();
}
<img id='myimage' src='image.jpg'/>
tintImage(
    document.getElementById('myImage'),
    "#550000" // for a redish tint
);