有没有一种使用JavaScript将PNG图像的白色背景转换为透明背景的方法?

4
我有一堆只有黑色文字和白色背景的.png图片。到目前为止,这些图片都在屏幕上显示为白色背景,所以没有问题;但现在,我要改变背景颜色。问题是,当放置在浅灰色背景下时,文本看起来有点不对劲,因此我想知道JavaScript(jQuery也可以)是否能够实时将.png文件的白色背景转换为透明背景。我对此问题感兴趣的是服务器端解决方案(例如通过图像库运行脚本并以编程方式完成所有图像),而且大量的图像使手动处理方法不切实际。
有人知道如何做到这一点吗?搜索没有发现任何内容。请注意,我不要IE的.png修复方法!
如果有方法,这样的过程会带来什么开销?
感谢您的任何帮助!

虽然可能有一种方法可以做到这一点,可能使用特定于浏览器的功能,但这并不值得。只需找到一个可以批量转换的应用程序。ImageMagick的命令行实用程序可能有一些可以帮助你的东西。 - Brian Donovan
谢谢Brian。我想这可能是最终的解决方案,但我想先探索一下我的选择。 - Josh Leitzel
2个回答

6
我能想到的最接近你要求的是IE特有的chroma滤镜,它可以做到你想要的效果(类似于蓝屏,其中任何蓝色都将变为透明,在你的情况下,任何白色都将变为透明)...请参见:http://www.ssi-developer.net/css/visual-filters.shtml。 我没有找到其他浏览器或CSS3中的等效物。

可能可以创建一个脚本,查找文档中的所有图像,用画布元素替换它,将图像绘制在画布上,逐个像素地处理图像数据,如果像素是某种颜色,则将其alpha更改为0(透明)。

这里是该概念的快速POC...您需要在Web服务器上运行此代码才能在Chrome和FF上运行,它可以在IE9 beta上本地运行。

只需将图像更改为任何具有纯白色RGB(255,255,255)的图像即可。 它将通过将其alpha通道设置为0使图像中的任何白色像素变为透明。

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <style type="text/css">
      body { background-color: #00f; margin: 0px; padding: 0px; }
    </style>
    <script type="text/javascript" src="jquery-1.4.4.min.js"></script>
  </head>
  <body>
    <img src="test.png">
    <img src="test.png">
  </body>
  <script type="text/javascript">
    $(function() {
      $("img").each(function() {
        var $this = $(this);
        var tim = $this.get(0);
        var idx = $this.index();

        var canvas = null;
        var ctx = null;

        var img = new Image();
        img.onload = function() {
          copyImageToCanvas(img);
        };
        img.setAttribute("src", tim.src);

        function copyImageToCanvas(aImg) {
          canvas = document.createElement("canvas");

          var w = typeof aImg.naturalWidth == "undefined" ? aImg.width : aImg.naturalWidth;
          var h = typeof aImg.naturalHeight == "undefined" ? aImg.height : aImg.naturalHeight;

          canvas.id = "img" + idx;
          canvas.width = w;
          canvas.height = h;

          $this.replaceWith(canvas);

          ctx = canvas.getContext("2d");
          ctx.clearRect(0, 0, w, h);      
          ctx.drawImage(aImg, 0, 0);

          makeTransparent(aImg);
        }

        function makeTransparent(aImg) {

          var w = typeof aImg.naturalWidth == "undefined" ? aImg.width : aImg.naturalWidth;
          var h = typeof aImg.naturalHeight == "undefined" ? aImg.height : aImg.naturalHeight;
          var imageData = ctx.getImageData(0, 0, w, h);

          for (var x = 0; x < imageData.width; x++)
            for (var y = 0; y < imageData.height; y++) {
              var offset = (y * imageData.width + x) * 4;
              var r = imageData.data[offset];
              var g = imageData.data[offset + 1];
              var b = imageData.data[offset + 2];

              //if it is pure white, change its alpha to 0              
              if (r == 255 && g == 255 && b == 255)
                imageData.data[offset + 3] = 0;
            };

          ctx.putImageData(imageData, 0, 0);
        }
      });
    });
  </script>
</html>

谢谢你的回答,Jimmy!虽然它没有解决我的问题(这个问题可能在当前定义下是无法解决的),但你的回答非常有帮助。 - Josh Leitzel
我最初在jsfiddle上尝试,但是跨域问题使测试变得困难。在我的服务器上,我确认这段代码适用于我。这对我有用。谢谢。 - Kabkee

0

我所知道的JS图像处理唯一的选项是Pixastic,但它没有你想要的功能。据我所知,你必须在服务器端进行处理。


如果您在服务器端执行此操作,则可以使用AJAX返回新图像,以避免完整页面的回传。 - The Muffin Man

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