Search code examples
javascriptbase64

Is is possible to read pixel data from base64 images?


So here I have a base64 encoded png image:

iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

and I decoded it using atob(). It turns out to be:

PNG

IHDRo&åIDAT×cøÿÿ?Ã Ã Ð1ñXÍõ5ËÑIEND®B`

Is it possible to get out the color values from this string? (without using <canvas>)

PS: It seems like it is possible since I found a demo:
 http://labs.calyptus.eu/JSBin/Demo/Viewer.html
 But I am not sure how he did it.


Solution

  • In the source of the page you pointed, there's a function that uses the PNG.js and some other utilities to do what you want:

    function show(data){
        var png = new PNG(data);
        var img = document.getElementById('image'), limg = document.getElementById('largeimage');
        document.getElementById('nativeimage').src = 'data:image/png;base64,' + data;
        img.innerHTML = '';
        limg.innerHTML = '';
        img.style.width = png.width + 'px';
        img.style.height = png.height + 'px';
        limg.style.width = (png.width * 3) + 'px';
        limg.style.width = (png.height * 3) + 'px';
        var line;
        while(line = png.readLine())
        {
            for (var x = 0; x < line.length; x++){
                var px = document.createElement('div'), px2 = document.createElement('div');
                px.className = px2.className = 'pixel';
                px.style.backgroundColor = px2.style.backgroundColor = '#' + line[x].toString(16).padRight('0', 6);
                img.appendChild(px);
                limg.appendChild(px2);
            }
        }
    }
    

    If you look at the loop in this function , you will notice that it's reading the PNG, line by line and ploting the pixels.

    A simplified example would be:

    var png = new PNG(data); // data is the base64 encoded data
    var line;
    var y = 0;
    while(line = png.readLine())
    {
        for (var x = 0; x < line.length; x++){
            var pixel = doSomethingWithPixelData(x, y, '#' + line[x].toString(16).padRight('0', 6));
        }
        y++;
    }
    
    function doSomethingWithPixelData(x, y, color) {
        // guess what? do something with pixel data here ;)
    }