如何在JavaScript中创建图像的文本二进制表示?

时间:2016-07-12 16:24:00

标签: javascript binary filereader bit arraybuffer

对于一个小项目,我想将图像转换为二进制表示(零和一)。因为我想在未配置为运行PHP,.NET的计算机上使用它,...我想在JavaScript中执行此操作。

目前,我设法使用ArrayBuffer读取了该文件,该文件为ArrayBuffer

但我对如何将此function ArrayBufferToBit(buffer) { // How to convert my array buffer to a textual bit-representation? 0 1 1 0 0 0... return buffer; } 转换为位表示无能为力。

我的当前版本可在此jsfiddle找到。

{{1}}

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

使用DataView

function ArrayBufferToBit(buffer) {
    var dataView = new DataView(buffer);
    var response = "", offset = (8/8); 
    // I assume we will read the entire file as a series of 8-bit integers, 
    // i.e. as a byte, hence my choice of offset.
    for(var i = 0; i < dataView.byteLength; i += offset) {
        response += dataView.getInt8(i).toString(2); 
        // toString is the secret sauce here.
    }
    return response;
}

Dataview让你读/写数字数据; getInt8将数据从字节位置(此处为0,传入的值)转换为ArrayBuffer到带符号的8位整数表示,toString(2)将8位整数转换为二进制表示格式(即1&#39; s和0&#39;)的字符串。

魔法&#39;通过注意我们将文件存储为字节,即8位整数并以8位整数表示读取它来获得偏移值。如果我们试图将字节保存的(即8位)文件读取为32位整数,我们会注意到32/8 = 4是字节空格的数量,这是我们的字节偏移值。

除了类型化数组之外,这是ArrayBuffer读取/写入的recommended way

  

ArrayBuffer对象用于表示通用的固定长度原始二进制数据缓冲区。你不能直接操纵ArrayBuffer的内容;相反,您创建一个类型化数组对象或一个DataView对象,它表示特定格式的缓冲区,并使用它来读取和写入缓冲区的内容。

除了带符号的8位表示外,您还可以获得各种表示(如float64甚至int32)。表示的选择无关紧要,因为toString(2)无论如何都会以二进制形式显示它(尽管二进制字符串的长度肯定会因显而易见的原因而改变!)。

注意,在这个例子中,我选择将整个文件表示为一系列8位整数,即逐字节读取。但是,一般情况下,DataView有助于混合齐次类型 - 例如,您可以将前12个字节读取为32位整数,将剩余的读取为64位。处理文件时通常首选DataView,因为可以通过这种方式处理不同的文件格式,因为DataView也可以处理来自不同体系结构的文件的字节序。

像这样的任务可以由类型化数组处理,如在@ le_m的答案中,或由DataView s处理 - 但是,DataView可以处理两个字节序(如果文件是通过网络从不同的CPU传输)问题和不同的文件格式(例如PDF文件,在主要内容之前有一些字节标题)。

答案 1 :(得分:1)

您需要遍历数组缓冲区的内容。您可以使用DataView作为该类型或类型化数组。

由于我们要读取单个字节,因此我们不需要担心系统的大或小字节序,并且可以安全地使用允许我们使用Uint8Array的{​​{1}}以便将所有元素组合成一个二进制字符串。

要将字节转换为二进制,我们可以使用Array.reduce()方法。

Number.toString(base)
function arrayBufferToBinary(buffer) {
  var uint8 = new Uint8Array(buffer);
  return uint8.reduce((binary, uint8) => binary + uint8.toString(2), "");
}

function fileToBinary(file, callback) {  
  var reader = new FileReader();
  reader.onload = (event) => callback(arrayBufferToBinary(reader.result));
  reader.readAsArrayBuffer(file);
}

var input = document.getElementById("file");
var output = document.getElementById("binary");

input.addEventListener("change", function(event) {
  var file = input.files[0];
  if (file) fileToBinary(file, (binary) => output.textContent = binary);
});
#binary {
  word-wrap: break-word;
}