从图像中读取二进制数据并使用JavaScript保存

Ben*_*uer 7 javascript html5 image binary-data filereader

我想读取图像的二进制数据,然后使用JavaScript将其再次保存到本地磁盘.

我写了一个小型演示,展示了这个用例.读取文件我用readAsBinaryString文件读取API(HTML5)来获取二进制数据.

我将二进制字符串写入文本字段,然后再从中读取数据以将其写入文件.如果我保存文件我的图像(我测试了几个JPEG)被破坏,所以你看不到任何有用的东西.

难道"readAsBinaryString"进行转换会导致二进制数据不正确吗?

看看我的演示应用程序,我做了一个小提琴.主要部分从这里开始:

reader.readAsBinaryString(file);
Run Code Online (Sandbox Code Playgroud)

dbe*_*dez 9

我已经在你的小提琴上测试了这个代码,它就像一个魅力:

  var contentType = '';

  window.saveImage = function() {
    var textToWrite = document.getElementById("inputTextToSave").value;

    var splittedTextToWrite = textToWrite.split(",");

    var u16 = new Uint16Array(splittedTextToWrite.length);

      for(i=0; i<splittedTextToWrite.length; i++){
          u16[i]=splittedTextToWrite[i];
      }
    var textFileAsBlob = new Blob([u16], {type: contentType});          

    var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;

    var downloadLink = document.createElement("a");
    downloadLink.download = fileNameToSaveAs;
    downloadLink.innerHTML = "Download File";
    if (window.webkitURL !== null) {
      // Chrome allows the link to be clicked
      // without actually adding it to the DOM.
      downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    }
    else {
      // Firefox requires the link to be added to the DOM
      // before it can be clicked.
      downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
      downloadLink.onclick = destroyClickedElement;
      downloadLink.style.display = "none";
      document.body.appendChild(downloadLink);
    }

    downloadLink.click();
  }

  function destroyClickedElement(event) {
    document.body.removeChild(event.target);
  }

  window.loadImage = function() {
    var file = document.getElementById("fileToLoad").files[0];

    var reader = new FileReader();
    reader.onload = function(event) {
      var data = event.target.result;

      var data16 = new Uint16Array(data);
      var text = [];
        for(i = 0; i<data16.length; i++){
            text.push(data16[i]);
        }

      document.getElementById("inputTextToSave").value = text;

      var imagePreview = document.getElementById("imagePreview");
      imagePreview.innerHTML = '';

      var dataURLReader = new FileReader();
      dataURLReader.onload = function(event) {
        // Parse image properties
        var dataURL = event.target.result;
        contentType = dataURL.split(",")[0].split(":")[1].split(";")[0];

        var image = new Image();
        image.src = dataURL;
        image.onload = function() {
          console.log("Image type: " + contentType);
          console.log("Image width: " + this.width);
          console.log("Image height: " + this.height);
          imagePreview.appendChild(this);
        };
      };
      dataURLReader.readAsDataURL(file);


    };
    //reader.readAsBinaryString(file);
    reader.readAsArrayBuffer(file);
  }
Run Code Online (Sandbox Code Playgroud)

我不是新手的专家HTML5 APIs,但我会尝试解释一下我所做的一切.

1)我已将a保存PNG到磁盘.(photo.png)

2)如果您有Linux,则可以使用此命令以十六进制格式查看文件的内容od -cx photo.png.如果不是,你需要一些十六进制编辑器.

十六进制的第一行photo.png显示如下:

       211   P   N   G  \r  \n 032  \n  \0  \0  \0  \r   I   H   D   R

       5089    474e    0a0d    0a1a    0000    0d00    4849    5244
Run Code Online (Sandbox Code Playgroud)

第二行中的每对数字代表上述符号的十六进制编码:5089是211 P的编码,50是P的十六进制值,而211是211(小端编码,前两个字节编码第二个符号,最后两个编码第一个符号)

3)而不是将文件读作a binaryString,我将其读作ArrayBuffer(它不进行编码转换).

4)当读取文件时,我将变换ArrayBuffer为a Uint16Array,并将每个值存储在一个数组中,以在文本区域显示其十进制值.它将值显示为十进制数列表,以逗号分隔.在这种情况下,第一个十进制数将是20617,这是5089十六进制的十进制等效数.

5)在保存文件之前,一些简单的代码会分割十进制值并将它们添加到新文件中Uint16Array.

它对我有用......这有点令人困惑,可能有人会以另一种方式使用API​​来获得更好,更有效的方法.