通过Javascript更改图像颜色

时间:2015-02-03 14:28:52

标签: javascript colors

我一直在寻找使用点击事件时更改图像的颜色。

我遇到了这篇文章,其中第一个和主要的回应与Mug的效果非常好。

但是,我需要使用class而不是ID,因为我需要更改多个图像的颜色。当我将代码更改为getElementsByClassName而不是byID时,它将不再有效。

我当然将ID =杯子更改为class = mug。

我无法在代码中的任何其他位置看到会导致问题,因此任何帮助都会受到赞赏。

我无法发布原文,所以在这里添加。原始链接是: How to change color of an image using jquery

这是代码:

<img src="mug.png" id="mug" width="25%" height="25%" onload="getPixels(this)" />
<input type="text" id="color" value="#6491ee" />
<input type="button" value="change color" onclick="changeColor()">

<script type="text/javascript">
    var mug = document.getElementById("mug");
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var originalPixels = null;
    var currentPixels = null;

    function HexToRGB(Hex)
    {
        var Long = parseInt(Hex.replace(/^#/, ""), 16);
        return {
            R: (Long >>> 16) & 0xff,
            G: (Long >>> 8) & 0xff,
            B: Long & 0xff
        };
    }

    function changeColor()
    {
        if(!originalPixels) return; // Check if image has loaded
        var newColor = HexToRGB(document.getElementById("color").value);

        for(var I = 0, L = originalPixels.data.length; I < L; I += 4)
        {
            if(currentPixels.data[I + 3] > 0)
            {
                currentPixels.data[I] = originalPixels.data[I] / 255 * newColor.R;
                currentPixels.data[I + 1] = originalPixels.data[I + 1] / 255 * newColor.G;
                currentPixels.data[I + 2] = originalPixels.data[I + 2] / 255 * newColor.B;
            }
        }

        ctx.putImageData(currentPixels, 0, 0);
        mug.src = canvas.toDataURL("image/png");
    }

    function getPixels(img)
    {
        canvas.width = img.width;
        canvas.height = img.height;

        ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, img.width, img.height);
        originalPixels = ctx.getImageData(0, 0, img.width, img.height);
        currentPixels = ctx.getImageData(0, 0, img.width, img.height);

        img.onload = null;
    }
</script>

由于

3 个答案:

答案 0 :(得分:2)

我不知道您正在尝试的作业的自定义方式,但一个简单的修复方法是使用过滤器创建第二个类,然后在click事件中添加该类。

<img src='mug.png' id='mug' class='unfiltered-pic'  onclick="changeColor(this)>
<style>
.unfiltered-pic {
     width: 25%
     height: 25%
}

.filtered-pic {
    filter: hue-rotate(/*degree on color wheel*/deg)
}
</style>
<script>
function changeColor(element) {
     element.setAttribute('class', 'filtered-pic');
}
</script>

您可以通过css-filters here选择各种过滤器。使用hue-rotate更改色调(颜色)。使用色轮确定您要去的地方。

如果您想切换到使用类一次更改所有这些,您可以改为:

<img src='mug.png' id='mug' class='unfiltered-pic'  onclick="changeColor()>
<style>
.unfiltered-pic {
     width: 25%
     height: 25%
}

.filtered-pic {
    filter: filter function /*See Link*/
}
</style>
<script>
var pics = document.getElementByClassName('unfiltered-pic')
function changeColor() {
     for(var i=0; i < pics.length; i++) {
         pics[i].setAttribute('class', 'filtered-pic');
     }
}
</script>

如果您需要任何澄清或其他帮助,请与我们联系。

答案 1 :(得分:1)

我认为它可能与浏览器支持有关,因为document.getElementByClassName("mug");应该返回一个元素数组(旧版浏览器可能不支持它)。在这一点上,很容易迭代每个杯子并改变颜色,如此

<img src="mug.png" id="mug" width="25%" height="25%" onload="getPixels(this)" />
<input type="text" id="color" value="#6491ee" />
<input type="button" value="change color" onclick="changeMugsColor()">

<script type="text/javascript">
    var mug = document.getElementsByClassName("mug");
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");
    var originalPixels = null;
    var currentPixels = null;

    function HexToRGB(Hex)
    {
        var Long = parseInt(Hex.replace(/^#/, ""), 16);
        return {
            R: (Long >>> 16) & 0xff,
            G: (Long >>> 8) & 0xff,
            B: Long & 0xff
        };
    }

    function changeMugsColor() {
        for (var ii = 0; ii < mug.length; ii++) {
            changeColor(mug[ii]);
        }
    }

    function changeColor(amug)
    {
        if(!originalPixels) return; // Check if image has loaded
        var newColor = HexToRGB(document.getElementById("color").value);

        for(var I = 0, L = originalPixels.data.length; I < L; I += 4)
        {
            if(currentPixels.data[I + 3] > 0)
            {
                currentPixels.data[I] = originalPixels.data[I] / 255 * newColor.R;
                currentPixels.data[I + 1] = originalPixels.data[I + 1] / 255 * newColor.G;
                currentPixels.data[I + 2] = originalPixels.data[I + 2] / 255 * newColor.B;
            }
        }

        ctx.putImageData(currentPixels, 0, 0);
        amug.src = canvas.toDataURL("image/png");
    }

    function getPixels(img)
    {
        canvas.width = img.width;
        canvas.height = img.height;

        ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, img.width, img.height);
        originalPixels = ctx.getImageData(0, 0, img.width, img.height);
        currentPixels = ctx.getImageData(0, 0, img.width, img.height);

        img.onload = null;
    }
</script>

我没有运行代码但它应该可以运行

答案 2 :(得分:0)

好的,花了一些时间,但通过结合给出的建议和额外搜索找到了满足我需求的解决方案。

到目前为止,每个建议都让我知道,但是我需要的具体功能存在一些问题,所以我发布这个以防万一。

我正在使用&lt; svg&gt;元素:

我需要一张主图像,如果单击图像,或者点击主图像外的按钮,顶部的一些较小的图像会改变颜色。

<div style="position: absolute; top: 0px; left: 0px;"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="0px" height="0px"><defs><filter id="desaturate"> <feColorMatrix 
  type="matrix"
  values="0.5 0 0 0 0
          0.2 0 0 0 0
          0.9 0 0 0 0
          0 0 0 1 0" /></filter></defs></svg></div>

值设置颜色变化。这是试验和错误atm,因为我还没有找到一个很好的颜色指南,但有足够的周围来得到。

我遇到了使用&lt;随机空间和定位问题。 svg&gt;元件。所以我把它放在一个绝对定位的潜水中,并将元素的大小设置为'0''0',这样它就不会占用任何空间,也不会影响页面上的任何其他内容。

ID指定此特定颜色。然后,您可以将此颜色更改应用于任意数量的图像,如下所示:

<div style="position: relative; top: 000px; left: 000px; z-index: 1; display: inline;">
<svg class="svgClass" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="450px" height="900px">
<image xlink:href="main_image.png" width="450" height="900" />
<image xlink:href="small_image1.png" class="ChangeImageColour ChangeImageColourClick" width="79" height="198" x="110px" y="100px" />
<image xlink:href="small_image2.png" class="ChangeImageColour ChangeImageColourClick" width="79" height="198" x="150px" y="130px" /></svg></div>

同样,为避免SVG的位置和间距问题,我设置了&lt;的大小。 svg&gt;图像的元素与主图像的大小相同,并将它们全部放在&lt; div>然后可以将其放置在页面上的正确位置。如果您希望图像以这种方式重叠,则需要将所有图像保持在同一&lt; svg&gt;元素或您可能会在某些浏览器中获得显示位置和间距问题。

您可以使用“x”和“y”将每个图像分别放置在主图像的顶部。您还必须指定图像的高度和宽度。

一旦你有了&lt; svg&gt;指定颜色,你的&lt; svg&gt;对于图像的元素,您现在只需要使用类和ID属性以及以下代码将该颜色应用于所需的图像:

<script>
  var $shape = $( '.ChangeImageColour' );
$( '.ChangeImageColourClick' ).click(function() {
          if ( $shape.attr( 'filter' ) )
     $shape.removeAttr( 'filter' );
  else
     $shape.attr( 'filter', 'url(#desaturate)' );
});
</script>

我希望在图像或按钮上的单击事件以太后发生颜色更改。只需创建一个匹配“click”calss的按钮,在本例中为“ChangeImageColourClick”。因此,您可以创建要点击的任何内容并更改颜色。此单击添加要更改的设置颜色的ID(#desaturate)。如果任何匹配元素已具有该ID,则将其删除。

这会产生切换颜色变化的效果。它将改变同一类的任何匹配图像的颜色。

如果不需要,您当然不能使用点击事件,或者开始使用颜色更改'打开'并点击删除等。

注意:你可以有多个&lt; svg&gt;带有图像的元素并应用相同的颜色变化。只要确保你设置&lt; svg&gt;元素尺寸到你想要的确切尺寸,即使它是0.如果你把它留空,那么你会遇到一些间距问题。

我需要将图像放在同一个&lt; svg&gt;因为它们是占用页面上相同空间的png图像。如果您的图像没有重叠,则应使用单独的&lt; svg&gt;元素或每个图像或图像集,并设置&lt; svg&gt;元素到那个图像的大小,你不应该在一些浏览器中有奇怪的间距和定位问题。

我认为这解释了一切。

它非常适合我需要的东西,并且是一个相当简洁的编码,特别是因为你只需设置一次颜色并应用于多个图像。

请注意我提供的一些注意事项,以确保它能够根据您的需要显示。

感谢所有帮助,如果有任何相关内容需要更新。

如果您遇到任何问题,请在此处发帖。我不是专家,但现在已经看了很多,并且可能已经尝试并测试了大多数陷阱