0

I'm switching an implementation of a cross-site request for an image converted to base 64 from Canvas to XMLHttpRequest and FileReader, so that it can be used inside of web workers. And I want to know if there's a way to get the image width and height from the get-go.

The new function

var convertFileToDataURLviaFileReader = function (url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function () {
        var reader = new FileReader();
        reader.onloadend = function () {
            callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
    };

    // Our workaround for the Amazon CORS issue
    // Replace HTTPs URL with HTTP
    xhr.open('GET', url.replace(/^https:\/\//i, 'http://'));
    xhr.send();
}

Our old Function

var convertImgToDataURLviaCanvas = function(url, callback, outputFormat) {
    var img = new Image();
    img.crossOrigin = 'Anonymous';
    img.onload = function () {
        var canvas = document.createElement('CANVAS');
        var ctx = canvas.getContext('2d');
        var dataURL;
        canvas.height = this.height;
        canvas.width = this.width;
        ctx.drawImage(this, 0, 0);
        dataURL = canvas.toDataURL(outputFormat);

        var allInfo = {
            data: dataURL,
            width: this.width,
            height: this.height
        }

        // Add height and width to callback
        callback(allInfo);
        canvas = null;
    };

    // Our workaround for the Amazon CORS issue
    // Replace HTTPs URL with HTTP
    img.src = url.replace(/^https:\/\//i, 'http://');
}

In the old function I can just get the height and width with canvas, and I do so inside of the var allInfo. Is there an equivalent for FileReader or some way to get the width and height inside of the new function?

To clarify, I am switching to the XMLHttpRequest because Web Workers don't have access to the DOM, so Canvas can't be used.

Erick
  • 2,488
  • 6
  • 29
  • 43

1 Answers1

1

Have a look at this code, it's just a quick rework of this example https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL

Is your reader.result a string in base 64 encoding ?

  <form>
    <input type="file" onchange="previewFile()"><br>
    <img src="" alt="Image preview..."><!-- height and width are not set -->
  </form>
  <script>
    var previewFile = () => {

      "use strict";

      let file = document.querySelector("input[type=file]").files[0];
      let fileReader = new FileReader();
      let preview = document.querySelector("img")

      fileReader.addEventListener("load", () => {
        preview.src = fileReader.result;
        // here preview.height and preview.width are accessible
        // if height and width are not set in the img element in the html
      });

      if (file) {
        fileReader.readAsDataURL(file);
      }
    };
  </script>
  • I think this will not work, because this `let preview = document.querySelector("img")` depends on the DOM, and Web Workers have no access to the DOM. – Erick Feb 01 '16 at 19:26
  • 1
    Sorry I missed the point. I take you want to parse the string to get the dimensions right ? Have a look at those links, the info you are looking for is in the header http://stackoverflow.com/questions/15327959/get-height-and-width-dimensions-from-base64-png https://en.wikipedia.org/wiki/Portable_Network_Graphics –  Feb 01 '16 at 19:50
  • 1
    What do you need to send to the web worker exactly ? It can take a js object as argument, so you could extract the dimensions from reader.result and add them as separate properties of your object. In this case both of the 2 methods allow you to do so. –  Feb 01 '16 at 20:04
  • That only works on PNG images while we accept any kind of image (Sadly). I did see that answer earlier. I think this might be nigh impossible. I'm considering just parsing the image dimensions in an external canvas and passing that to the other function, it's a bad approach but I can't find any way to get the image dimensions from the base64 string in a XMLHttpRequest that also happens to be inside a web worker. – Erick Feb 01 '16 at 23:09