12

I have a base64 encoded PNG. I need to get the color of a pixel using javascript. I assume I'll have to convert it back to a normal PNG. Can anyone point me in the right direction?

switz
  • 24,384
  • 25
  • 76
  • 101
  • Yes, you'll have to both base64-decode, and then decode the PNG stream in Javascript. This is a hard (though not impossible) problem. You might be actually constrained to this requirement, but if you give a little more context, you might get some broader-scoped answers providing other workarounds in the situation. E.g. where is the PNG data coming from? Where is it going to? Do you need a single, fixed pixel from each image? Do you have any server support? Etc. – Ben Zotto Aug 20 '10 at 05:06
  • To make it a little more detailed: I'm attempting to write a Safari Extension. It will mimic the abilities of Colorzilla for Firefox. The only way I have seen that this is possible, is if you take a "screenshot". The output is in Base64 PNG. I would eventually need to track the mouse, then sync that up with the image to pull the clicked pixel's data off of the image. – switz Aug 20 '10 at 05:08
  • @BenZotto Why would it be hard? – Melab Feb 02 '17 at 13:50

1 Answers1

21

Create an Image object with the base64 image as the source. Then you can draw the image to a canvas and use the getImageData function to get the pixel data.

Here's the basic idea (I haven't tested this):

var image = new Image();
image.onload = function() {
    var canvas = document.createElement('canvas');
    canvas.width = image.width;
    canvas.height = image.height;

    var context = canvas.getContext('2d');
    context.drawImage(image, 0, 0);

    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

    // Now you can access pixel data from imageData.data.
    // It's a one-dimensional array of RGBA values.
    // Here's an example of how to get a pixel's color at (x,y)
    var index = (y*imageData.width + x) * 4;
    var red = imageData.data[index];
    var green = imageData.data[index + 1];
    var blue = imageData.data[index + 2];
    var alpha = imageData.data[index + 3];
};
image.src = base64EncodedImage;
Matthew Crumley
  • 101,441
  • 24
  • 103
  • 129
  • Thank you very much! I then took that and converted to hex codes. Is there any way to pull hex data from getImageData, or do I have to convert it. Either way, thanks! – switz Aug 20 '10 at 16:18
  • @Switz: Not directly. You just have to convert each channel individually with `toString(16)` or something similar. – Matthew Crumley Aug 20 '10 at 17:55