Skip to content

Instantly share code, notes, and snippets.

@deepak1556
Created December 7, 2013 17:30
Show Gist options
  • Save deepak1556/7845796 to your computer and use it in GitHub Desktop.
Save deepak1556/7845796 to your computer and use it in GitHub Desktop.
webp support using libwebpjs (webp->png in canvas)
WebPDecodeAndDraw = function (data) {
var decoder = new WebPDecoder();
var bitmap = decoder.WebPDecode(data, data.length);
if (bitmap) {
//Draw Image
var output = ctx.createImageData(canvas.width, canvas.height);
var biWidth = canvas.width;
var outputData = output.data;
for (var h=0;h<canvas.height;h++) {
for (var w=0;w<canvas.width;w++) {
outputData[0+w*4+(biWidth*4)*h] = bitmap[0+w*4+(biWidth*4)*h];
outputData[1+w*4+(biWidth*4)*h] = bitmap[1+w*4+(biWidth*4)*h];
outputData[2+w*4+(biWidth*4)*h] = bitmap[2+w*4+(biWidth*4)*h];
outputData[3+w*4+(biWidth*4)*h] = bitmap[3+w*4+(biWidth*4)*h];
};
}
ctx.putImageData(output, 0, 0);
var dataURL = canvas.toDataURL("image/png");
document.getElementById("dec").src=dataURL;
}
};
function getImage(img) {
// Create an empty canvas element
canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
// Copy the image contents to the canvas
ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
WebPDecodeAndDraw(ctx.getImageData(0,0,ctx.canvas.width,ctx.canvas.height)['data']);
}
@GAYFUCK222222
Copy link

i have to figure out how to read out of a WEBP file and decode it and fetch pixel data

@shmohawk
Copy link

shmohawk commented Dec 6, 2024

I tried loading an image with jQuery:

$.get("/images-webp/1.webp", function(data){
    console.log(data);
    WebPDecodeAndDraw(data);
 });

It doesn't work due to formatting issues. It seem that you have to modify the loadfile() function to accept URLs outside of the example folder (or figure out what's wrong with the formatting).

@shmohawk
Copy link

shmohawk commented Dec 6, 2024

function createRequestObject() {
        var ro;
        var browser = navigator.appName;
        if (browser == "Microsoft Internet Explorer") {
            ro = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
            ro = new XMLHttpRequest();
        }
        return ro;
    }

    var http = createRequestObject();

    function convertResponseBodyToText(IEByteArray) {
        var ByteMapping = {};
        for (var i = 0; i < 256; i++) {
            for (var j = 0; j < 256; j++) {
                ByteMapping[String.fromCharCode(i + j * 256)] =
                    String.fromCharCode(i) + String.fromCharCode(j);
            }
        }
        var rawBytes = IEBinaryToArray_ByteStr(IEByteArray);
        var lastChr = IEBinaryToArray_ByteStr_Last(IEByteArray);
        return rawBytes.replace(/[\s\S]/g,
            function(match) {
                return ByteMapping[match];
            }) + lastChr;
    }

    function loadfile(filename, type, imgelement) {
        if (typeof type === 'undefined') type = 'dec';
        //document.getElementById('testbild').innerHTML='server query....';
        if (type === 'dec') {
            http.open('get', filename, false);

            if (http.overrideMimeType)
                http.overrideMimeType('text/plain; charset=x-user-defined');
            else
                http.setRequestHeader('Accept-Charset', 'x-user-defined');
            http.send(null);
            if (http.status === 200) {
                var response = http.responseText.split('').map(function(e) {
                    return String.fromCharCode(e.charCodeAt(0) & 0xff)
                }).join('');
                var canvas = document.createElement("canvas");
                try {
                    WebPDecodeAndDraw(response, canvas);
                    jQuery(imgelement).attr("src", canvas.toDataURL());
                } catch(error) {}
          } else { console.log("Request failed: "+http.status);}
        }
    }

    function convertBinaryToArray(binary) {
        var arr = new Array();
        var num = binary.length;
        var i;
        for (i = 0; i < num; ++i)
            arr.push(binary.charCodeAt(i));
        return arr;
    }

    function WebPDecodeAndDraw(data, canvas) {
        var start = new Date();

        ///--------- libwebpjs 0.2.0 decoder code start ---------------------------------------------
        var WebPImage = {
            width: {
                value: 0
            },
            height: {
                value: 0
            }
        }
        var decoder = new WebPDecoder();
   
        data = convertBinaryToArray(data); //unkonvertierung in char
        //Config, you can set all arguments or what you need, nothing no objeect 
        var config = decoder.WebPDecoderConfig;
        var output_buffer = config.j;
        var bitstream = config.input;

        if (!decoder.WebPInitDecoderConfig(config)) {
            alert("Library version mismatch!\n");
            return -1;
        }

        var StatusCode = decoder.VP8StatusCode;

        status = decoder.WebPGetFeatures(data, data.length, bitstream);
        if (status != 0) {
            alert('error');
        }

        var mode = decoder.WEBP_CSP_MODE;
        output_buffer.J = 4;

        status = decoder.WebPDecode(data, data.length, config);

        var ok = (status == 0);
        if (!ok) {
            alert("Decoding failed.\n");
            //fprintf(stderr, "Status: %d (%s)\n", status, kStatusMessages[status]);
            return -1;
        }

        //alert("Decoded %s. Dimensions: "+output_buffer.width+" x "+output_buffer.height+""+(bitstream.has_alpha.value ? " (with alpha)" : "")+". Now saving...\n");
        var bitmap = output_buffer.c.RGBA.ma;
        //var bitmap = decoder.WebPDecodeARGB(data, data.length, WebPImage.width, WebPImage.height);

        ///--------- libwebpjs 0.2.0 decoder code end ---------------------------------------------

        var end = new Date();
        var bench_libwebp = (end - start);

        if (bitmap) {
            //Draw Image
            var start = new Date();
            var biHeight = output_buffer.height;
            var biWidth = output_buffer.width;

            canvas.height = biHeight;
            canvas.width = biWidth;

            var context = canvas.getContext('2d');
            var output = context.createImageData(canvas.width, canvas.height);
            var outputData = output.data;

            for (var h = 0; h < biHeight; h++) {
                for (var w = 0; w < biWidth; w++) {
                    outputData[0 + w * 4 + (biWidth * 4) * h] = bitmap[1 + w * 4 + (biWidth * 4) * h];
                    outputData[1 + w * 4 + (biWidth * 4) * h] = bitmap[2 + w * 4 + (biWidth * 4) * h];
                    outputData[2 + w * 4 + (biWidth * 4) * h] = bitmap[3 + w * 4 + (biWidth * 4) * h];
                    outputData[3 + w * 4 + (biWidth * 4) * h] = bitmap[0 + w * 4 + (biWidth * 4) * h];

                };
            }

            context.putImageData(output, 0, 0);
            var end = new Date();
            var bench_canvas = (end - start);

           return canvas;
        }
    }

    jQuery("img[src$='webp']").each(function(index) {
        loadfile(jQuery(this).attr("src"), "dec", this);
    });

This is for libwebpjs 0.2.0. You may want to port it to libwebpjs 0.6.0, and make the XMLHTTPRequest to be concurrent.

@GAYFUCK222222
Copy link

GAYFUCK222222 commented Dec 8, 2024 via email

@superRaptor911
Copy link

How to convert animated webp?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment