3

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

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

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

4

2 回答 2

9

转换为 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";
<canvas id=c width=500 height=400></canvas>

到 1 位

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

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

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

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

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

于 2013-09-09T21:38:16.940 回答
1

您可以使用像FileSaver.js这样的库。并按照BMP 文件格式规范手动写出位图文件。

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

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的一些信息。

于 2013-09-09T13:39:07.780 回答