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']);
}
@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.

@Noob-101-8988
Copy link

Noob-101-8988 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