0

I need to get the pixel data from a random user's Facebook profile image so I can pass it through Emscripten to our C++ app. That is, I need the RGB values of each pixel. I've tried lots of different ways, using the Javascript FBSDK, graph calls, downloading images, and trying to draw to a canvas I've created but I run into all sorts of issues, e.g. cross domain problems. I don't need it to be rendered to a visible canvas, I just need toe data to pass back to our app.

Is there a simple way please ?

user3162134
  • 287
  • 1
  • 10
  • Cross-domain restrictions are not based on whether you need it to be “visible” or not. If Facebook does not return those image CORS-enabled, then you can not do it client side. – CBroe Dec 18 '15 at 15:11
  • I can load an image, create a canvas, draw the image to a canvas, but as soon as I call getImageData on the canvas context, I get the security error - The canvas has been tainted by cross-origin data. It works fine if the image is stored locally, so I believe we can either use a proxy server (slow), or write the image locally and load back in (could cause issues if not allowed by user). Is there any other way anyone can think of please ? – user3162134 Dec 21 '15 at 10:28

1 Answers1

0

You can get the image pixel data from Facebook, fetching the image via an Ajax request rather than an img tag.

Specifically, you can:

  • Fetch the image data using an XMLHttpRequest
  • Wrap up the data in a Blob
  • Set the src of an Image to an object URL of the blob
  • On load of the image, put the image on a canvas, using the canvas context's drawImage
  • Get the pixel data using the context's getImageData

The below. code works for me, on Chrome, without any security issues

document.addEventListener('DOMContentLoaded', function() {
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'arraybuffer';
  xhr.addEventListener("load", onResponse);
  xhr.open("GET", "http://graph.facebook.com/61308470/picture");
  xhr.send();

  var image = new Image();
  var canvas = document.getElementById('canvas');
  var context = canvas.getContext('2d');

  function onResponse() {
    var blob = new Blob([xhr.response], {type: 'image/jpeg'});
    var url = (window.URL || window.webkitURL).createObjectURL(blob);
    image.src = url;
  }

  image.onload = function() {
    context.drawImage(image, 0, 0);
    var data = context.getImageData(0, 0, 50, 50).data;

    // Pixel data of the image
    console.log(data);

    // Cleanup
    (window.URL || window.webkitURL).revokeObjectURL(url);
  }
});

You can see this at http://plnkr.co/edit/fEwoIQRQhaCDRHkwNdvr?p=preview

For reference, it looks like the Facebook profile pictures do set the headers for cross domain ajax. Specifically, the responses set access-control-allow-origin: *.

I based this on this answer to "Using raw image data from ajax request for data URI"

Community
  • 1
  • 1
Michal Charemza
  • 25,940
  • 14
  • 98
  • 165