2014-02-01 1 views
7

Я хочу прочитать двоичные данные изображения, а затем сохранить его снова на свой локальный диск с помощью JavaScript.Прочитайте двоичные данные из изображения и сохраните его с помощью JavaScript

Я написал небольшую демонстрацию, которая показывает этот прецедент. Чтобы прочитать файл, я использую readAsBinaryString из File Reader API (HTML5) для получения двоичных данных.

Я пишу двоичную строку в текстовое поле, из которого я затем снова прочитал данные, чтобы записать их в файл. Если я сохраню файл, мои изображения (я протестировал несколько JPEG-файлов) сломаны, поэтому вы не увидите ничего полезного.

Может быть, что «readAsBinaryString» делает преобразование, которое делает двоичные данные неверными?

Чтобы посмотреть мое демо-приложение, я сделал fiddle. Основная часть начинается здесь:

reader.readAsBinaryString(file); 

ответ

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

Я не эксперт по новому HTML5 APIs, но я буду попытайтесь немного объяснить, что я сделал.

1) Я сохранил 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 

Каждая пара чисел во второй строке представляют шестнадцатеричное кодификации символа выше: 5089 является кодификация 211 P, 50 - это шестнадцатеричное значение для P и 89 для 211 (кодирование с малой конечностью, первые два байта кодируют второй символ, последние два кодируют первый символ)

3) Вместо того, чтобы читать файл как binaryString, я читаю он как ArrayBuffer (он не делает преобразования кодировки).

4) Когда файл читается, я преобразовываю ArrayBuffer в Uint16Array и сохраняю каждое значение в массиве, чтобы показать его десятичное значение в текстовой области. Он показывает значения как список десятичных чисел, разделенных запятой. Первое десятичное число в этом случае будет 20617, что является десятичным эквивалентом для шестнадцатеричного числа 5089.

5) Перед сохранением файла некоторый простой код разбивает десятичные значения и добавляет их в новый Uint16Array.

Это сработало для меня ... Это немного запутанно, и, вероятно, кто-то получит более эффективный подход, используя API по-другому.

+0

Большое спасибо за этот замечательный и подробный ответ! Я просто проследил все с помощью шестнадцатеричного редактора в Windows 8. Он отлично работает! Даже файлы JPEG могут быть прочитаны и записаны. Я пересмотрел свою скрипку, чтобы все могли увидеть решение: http://jsfiddle.net/qz498/1/ - Большое вам спасибо! –

+0

Эта скрипка искажает мое изображение при сохранении. Это все еще работает для вас? –

+0

Простите, Кристиан, я не видел вашего вопроса до нескольких дней назад. Если вы посмотрите на скрипку Бенни, вы увидите, что у меня есть другой код js от того, который я предложил. Если вы используете эту скрипку http://jsfiddle.net/ocqu253m/1/, я надеюсь, вы найдете ее в порядке. Извините, это немного поздно :) – dbermudez

Смежные вопросы