Search code examples
javascriptimagetifflibtiff

Display Existing TIFF File Using the seikichi/tiff Library


This is the JavaScript code I use to load files from an input element. Image format includes jpeg, png, tiff.

$(document).ready(function() {
  FileDetails = function() {

    var input = document.getElementById('fileUpload');
    var output = document.getElementById('tblUpload');

    //' + (URL || webkitURL).createObjectURL(input.files[i]) +'

    output.innerHTML = '<tr>';
    output.innerHTML += '<th class="thStyle" style="width: 400px;"><b>File Name</b></th><th class="thStyle" style="width: 150px;"><b>Preview Image</b></th>';
    for (var i = 0; i < input.files.length; ++i) {

      output.innerHTML += '<td style="padding: 10px; width: 400px;">' +
        input.files[i].name + '</td>' +
        '<td style="padding: 10px; width: 150px; color: #0d47a1">' +
        '<a target="_blank" href="' + (URL || webkitURL).createObjectURL(input.files[i]) + '">Show</a></td>';

    }
    output.innerHTML += '</tr>';
  }
});

Now, how can I use the seikichi/tiff library to display tiff files?

I have been testing all sort of picture formats but the tiff files format always asks to be downloaded. Others such as jpeg, png can be displayed.


Solution

  • You need to convert the File from a TIFF first. Right now the file is handed as a binary file and the browser doesn't know what to do with it, hence it asks the user to download instead.

    You need to actually use the tiff library to parse and convert the file to something the browser can display.

    The steps are simple:

    var tiff = new Tiff({buffer: arrayBuffer});
    var canvas = tiff.toCanvas();
    

    But you first needs to convert the File blob into an ArrayBuffer. For this you can use FileReader(). Then when you have the ArrayBuffer pass it to an TIFF instance. The result is then converted to a canvas and shown.

    Live Example

    snapshot

    Note: for production you have to of course implement checks to see if the file is indeed a Tiff (for example by using file.type), error handling etc.

    document.querySelector("input").onchange = function() {
    
      // convert File blob to ArrayBuffer using a FileReader
      var fileReader = new FileReader();
      
      fileReader.onload = function() {                     // file is now ArrayBuffer:
        var tiff = new Tiff({buffer: this.result});        // parse and convert
        var canvas = tiff.toCanvas();                      // convert to canvas
        document.querySelector("div").appendChild(canvas); // show canvas with content
      };
      
      fileReader.readAsArrayBuffer(this.files[0]);         // convert selected file
    };
    <script src="https://cdn.rawgit.com/seikichi/tiff.js/master/tiff.min.js"></script>
    <label>Select TIFF file: <input type=file></label><div></div>

    So to load multiple files you would do the same in a loop:

    document.querySelector("input").onchange = function() {
    
      var files = this.files, fileReader;
    
      for(var i = 0; i < files.length; i++) {
        fileReader = new FileReader();
        fileReader.onload = handler;
        fileReader.readAsArrayBuffer(files[i]);            // convert selected file
      }
      
      function handler() {                                 // file is now ArrayBuffer:
        var tiff = new Tiff({buffer: this.result});        // parse and convert
        var canvas = tiff.toCanvas();                      // convert to canvas
        document.querySelector("div").appendChild(canvas); // show canvas with content
      };
    };
    <script src="https://cdn.rawgit.com/seikichi/tiff.js/master/tiff.min.js"></script>
    <label>Select TIFF file: <input type=file multiple></label><div></div>