从图像读取二进制数据并使用JavaScript保存 [英] Read binary data from an image and save it with JavaScript

查看:63
本文介绍了从图像读取二进制数据并使用JavaScript保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to read the binary data of an image and then save it again to my local disk with JavaScript.

我编写了一个小示例,演示了此用例.要读取文件,我使用了 File Reader API 中的 readAsBinaryString ./strong>(HTML5)来获取二进制数据.

I wrote a small demo that shows this use-case. To read the file I use readAsBinaryString from the File Reader API (HTML5) to get the binary data.

我将二进制字符串写入文本字段,然后从该文本字段再次读取数据以将其写入文件.如果保存文件,则我的图像(我测试了几个JPEG)已损坏,因此您看不到任何有用的信息.

I write the binary string into a textfield from which I then read the data again to write it to a file. If I save the file my images (I tested several JPEGs) are broken so you cannot see anything useful.

可能是"readAsBinaryString"进行了转换,使二进制数据不正确吗?

Can it be that "readAsBinaryString" makes a conversion which makes the binary data incorrect?

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

To have a look at my demo application I made a fiddle. The main part starts here:

reader.readAsBinaryString(file);

推荐答案

我已经在您的小提琴上测试了此代码,它的工作原理很吸引人:

I have tested this code on your fiddle and it has worked like a charm:

  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);
  }

我不是新版HTML5 APIs的专家,但我将尝试解释一下我所做的事情.

I'm not an expert on the new HTML5 APIs, but I will try to explain a bit what I have done.

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

1) I have saved a PNG to disk. (photo.png)

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

2) If you have Linux, you can see the contents of the file in hexadecimal format with this command od -cx photo.png. If not you need some hexadecimal editor.

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

The first lines of photo.png in hexadecimal show something like this:

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

       5089    474e    0a0d    0a1a    0000    0d00    4849    5244

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

Each pair of numbers in the second line represent the hexadecimal codification of the symbol above: 5089 is the codification of 211 P, 50 is the hex value for P and 89 for 211 (little endian codification, the first two bytes encodes the second symbol, the last two encodes the first symbol)

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

3) Instead of read the file as a binaryString, I read it as an ArrayBuffer (it doesn't make encoding conversions).

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

4) When the file is read, I transform the ArrayBuffer into a Uint16Array, and store each value in an array to show its decimal value on your text area. It shows the values as a list of decimal numbers, comma separated. The first decimal number will in this case will be 20617, which is the decimal equivalent for the 5089 hexadecimal.

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

5) Prior to saving the file, some simple code splits the decimal values and add them to a new Uint16Array.

它为我工作...有点令人困惑,可能有人会得到更好的成绩.另一种使用API​​的更有效的方法.

It worked for me... It's a bit confusing and probably someone will get a better & more efficient approach using the APIs in another way.

这篇关于从图像读取二进制数据并使用JavaScript保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆