【问题标题】:Create 1-bit bitmap from HTML Canvas in javascript在 javascript 中从 HTML Canvas 创建 1 位位图
【发布时间】:2023-04-08 11:56:01
【问题描述】:

我需要从 HTML5 Canvas 中获取 1 位位图。

画布是黑白的。 但是,我只能将 toUrlData() 与 png/jpeg 输出一起使用,但找不到任何方法来生成位图(并将颜色深度更改为 1 位)。

对于这种类型的转换是否有任何可用的解决方案? 或者可能是一个可以编写位图图像的 javascript 库?

【问题讨论】:

    标签: javascript html canvas bitmap


    【解决方案1】:

    转换为 1 位

    Canvas 没有允许您保存 1 位图像的内置机制。画布是 32 位(24 位颜色,8 位 alpha),这需要标准使用通用算法来降低图像质量(这可能是为什么你不能从中保存 GIF 文件,但只能保存支持 24-位或更多)。

    为此,您需要使用Typed Arrays 自行构建文件格式。

    如果 1 位文件 格式 不是绝对要求,即您希望图像 显示 就好像它是 1 位的,您可以自己简单地转换内容.

    您可以使用此方法通过将 RGB 转换为亮度值并将图像转换为“1 位”,并使用阈值来确定它应该是“开”还是“关”:

    var ctx = c.getContext("2d"), img = new Image();
    img.onload = function() {
      ctx.drawImage(img, 0, 0, c.width, c.height);
    
      // Main code
      var idata = ctx.getImageData(0, 0, c.width, c.height),
          buffer = idata.data,
          len = buffer.length,
          threshold = 127,
          i, luma;
    
      for (i = 0; i < len; i += 4) {
        // get approx. luma value from RGB
        luma = buffer[i] * 0.3 + buffer[i + 1] * 0.59 + buffer[i + 2] * 0.11;
    
        // test against some threshold
        luma = luma < threshold ? 0 : 255;
    
        // write result back to all components
        buffer[i] = luma;
        buffer[i + 1] = luma;
        buffer[i + 2] = luma;
      }
      
      // update canvas with the resulting bitmap data
      ctx.putImageData(idata, 0, 0);
    };
    
    img.crossOrigin = "";
    img.src = "//i.imgur.com/BrNTgRFl.jpg";
    &lt;canvas id=c width=500 height=400&gt;&lt;/canvas&gt;

    将其保存为 BMP 文件(虽然是 24 位,但并非所有浏览器都支持):

    var bmp = canvas.toDataURL("image/bmp");
    

    另请参阅 this answer,了解如何自己构建和编写 BMP 格式。

    您也可以将此方法与低级方法一起使用,方法是使用此结果来打包位(每 8 个“位”需要打包成一个字节,对于 BMP 格式为小端序)。

    可以选择查看更简单的TrueVision TGA file format,或者还允许您使用大端字节的TIFF file format(顺便说一句,大多数 TIFF 格式都可以被浏览器读取)。

    【讨论】:

    • 这是一个updated fiddle,没有损坏的依赖项。
    • 感谢@Jackson 的努力(以及提示过时的代码)。我决定改为内联在最初编写答案时不是一个选项的代码,并稍微改进一般答案(没有双关语)。
    【解决方案2】:

    您可以使用像 FileSaver.js 这样的库。并按照BMP File Format specification手动写出位图文件。

    你会对结果数据做这样的事情:

    function saveData() {
        var arrayBuffer = new ArrayBuffer(data.length);
        var dataView = new DataView(arrayBuffer);
        for(var i = 0; i < data.length; i ++) {
            dataView.setUint8(i, data.charCodeAt(i));
        }
        var blob = new Blob([dataView], {type: "application/octet-stream"});
        saveAs(blob, "test.bmp");
    }
    

    如果您要这样做,您可能需要在 ArrayBufferDataView 上查找一些信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-03
      • 2019-09-18
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多