JavaScript: getting ImageData without canvas

JavascriptHtmlCanvas

Javascript Problem Overview


Is it possible to get an ImageData Object from an image which is not on the canvas but somewhere else in the DOM tree as a normal <img> ?

If yes, how?

Javascript Solutions


Solution 1 - Javascript

You have to create an in memory canvas and then draw on this canvas the image :

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var img = document.getElementById('myimg');
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0 );
var myData = context.getImageData(0, 0, img.width, img.height);

But this won't work if the image comes from another domain. This is a security restriction you can't get around if you have no control of the server (be careful that if you open your html file with file:// you'll have a lot of additional restrictions, use http://)

Solution 2 - Javascript

As already implied, canvas offers the only solution for creating ImageData objects.

If you are really set against using the canvas element to load image data (perhaps we are talking lte IE8), you could always consider parsing the base64 image data using the src location of an image object

http://blog.calyptus.eu/seb/2009/05/png-parser-in-javascript/

It's difficult, but if you must, could potentially parse images to an array this way.

https://github.com/devongovett/png.js/blob/master/png.js

This shows you how to load the data with an xhr request and parse the png data. Internally it uses the canvas for some other things but the subset you are interested in is canvas free. You would need to follow a similar implementation for each image format you are interested in.

I should mention that the image pixel reading limitations are identical in terms of security. You will never be able to read pixels that have come from a third party, with or without canvas. The XMLHTTPRequest is going to be bound to the governance of cross-domain policies. This prevents scripts from stealing third party content, which includes images that may contain sensitive user information.

If you need to read images on a third party domain (that don't require authentication to view), you should run an image proxy server on your domain which allows you to request images on the same domain. If you need to go to the trouble of that, it might be easier to simply provide the image data as a json array in the first place.

Solution 3 - Javascript

If you are using a webworker you can use OffscreenCanvas as an alternative for document.createElement('canvas')

  var response = await fetch(imageUrl);
  var fileBlob = await response.blob();
  var bitmap = await createImageBitmap(fileBlob);
  var canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
  var context = canvas.getContext('2d');
  context.drawImage(bitmap, 0, 0);
  var myData = context.getImageData(0, 0, bitmap.width, bitmap.height);

Note that support for OffscreenCanvas is limited: https://caniuse.com/#feat=offscreencanvas

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionclampView Question on Stackoverflow
Solution 1 - JavascriptDenys SéguretView Answer on Stackoverflow
Solution 2 - JavascriptMatt EschView Answer on Stackoverflow
Solution 3 - JavascriptGobius DolhainView Answer on Stackoverflow