Javascript以dataURL格式生成透明的1X1像素

use*_*628 12 javascript base64 png pixel image-processing

我想知道一种在JavaScript中生成单个像素的方法,将其转换为base64.理想的功能是:

function createPixel(hexColor, opacity){
   //...Calculate
   return base64DataURL;
}
Run Code Online (Sandbox Code Playgroud)

我对图像处理不是很熟悉.任何格式都可以(png,gif等).我想使用它来叠加背景图像,(是的,我可以使用rgba css3,但我试图将它与背景图像仅放在一个元素上,所以我不会将元素叠加在另一个元素之上以实现效果) .

提前致谢.

编辑:我不想使用canvas,我相信你可以使用canvas来获取base64 dataURL,但我相信它没有字符串操作那么快.此外,我并不担心将图像转换为base64,而是对创建图像更感兴趣.

小智 10

4 年多后,这里有一个更简单的解决方案,它生成标准 GIF,因此实际上可以在浏览器中工作(我无法让 PEM 解决方案在任何东西中工作),并且比 PEM/canvas 快一个数量级。唯一的缺点是 GIF 不支持 alpha 不透明度 - 但这可以通过 CSS 进行控制。

它基于这个 JSFiddle(未知的美丽作者),但进行了基本优化 - 重用 keyStr 并接受十六进制字符串('#FF0000')和十六进制文字(0xFF0000) - 后者更快(感谢icktoofay)。

<html>

<body onload="Test()">
  <script>
    function Test() {
      var img = new Image;
      img.src = createPixelGIF(0xff0000); // generate a red pixel data URI
      img.height = 100;
      img.width = 100; // optional: add dimensions
      document.body.appendChild(img); // add to the page
    }

    // ROUTINES =============

    var createPixelGIF = (function() {

      var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

      return function createPixelGIF(hexColor) {
        return "data:image/gif;base64,R0lGODlhAQABAPAA" + encodeHex(hexColor) + "/yH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
      }

      function encodeHex(hexColor) {
        var rgb;
        if (typeof hexColor == 'string') {
          var s = hexColor.substring(1, 7);
          if (s.length < 6) s = s[0] + s[0] + s[1] + s[1] + s[2] + s[2];
          rgb = [parseInt(s[0] + s[1], 16), parseInt(s[2] + s[3], 16), parseInt(s[4] + s[5], 16)];
        } else
          rgb = [(hexColor & (0xFF << 16)) >> 16, (hexColor & (0xFF << 8)) >> 8, hexColor & 0xFF];

        return encodeRGB(rgb[0], rgb[1], rgb[2]);
      }

      function encodeRGB(r, g, b) {
        return encode_triplet(0, r, g) + encode_triplet(b, 255, 255);
      }

      function encode_triplet(e1, e2, e3) {
        enc1 = e1 >> 2;
        enc2 = ((e1 & 3) << 4) | (e2 >> 4);
        enc3 = ((e2 & 15) << 2) | (e3 >> 6);
        enc4 = e3 & 63;
        return keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
      }

    })();
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

更新的 JSPerf 结果:http://jsperf.com/base64image/4(上面的代码是“createPixelGIF2”)。你会看到我尝试了进一步的优化(3+4),但似乎 JS 更喜欢堆栈操作而不是难以阅读的组合函数:)

我还添加了对画布方法的更新测试,由于某种原因,该测试排除了画布对象的实例化 - 这是在现实世界使用中看到的最大性能拖累。


Mat*_*all 6

这是使用<canvas>demo @ jsfiddle)的完全跨浏览器兼容的实现。

var canvas = document.createElement('canvas');

// http://code.google.com/p/explorercanvas/wiki/Instructions#Dynamically_created_elements
if (!canvas.getContext) G_vmlCanvasManager.initElement(canvas);

var ctx = canvas.getContext('2d');
canvas.width = 1;
canvas.height = 1;

// for simplicity, assume the input is in rgba format
function createPixel(r, g, b, a) {
    ctx.fillStyle = 'rgba(' + [r,g,b,a].join() + ')';
    ctx.fillRect(0,0,1,1);
    // 'data:image/png;base64,'.length => 22
    return canvas.toDataURL('image/png','').substring(22);
}
Run Code Online (Sandbox Code Playgroud)

我很想知道这与icktoofay 的答案在性能方面有何不同。请注意,这将不得不为 IE <9使用excanvas,这意味着那里的性能几乎肯定会更差(但有什么新功能)。

查看 jsperf:http ://jsperf.com/base64image