Base64 Conversion after AJAX load

366 views
Skip to first unread message

teddyj...@gmail.com

unread,
Sep 26, 2013, 12:52:21 AM9/26/13
to webp-d...@webmproject.org
I am storing WebP images in my CDN to decrease storage size and bandwidth. I would like to serve these images to all clients, occasionally via AJAX. I have no problem in IE or FF with an image that has an src preset in the HTML img tag.

My question is with loading an image in via AJAX. Images are stored as their base64 representation. When I set the src via JavaScript, the webpjs will not go back and convert the image to a format that is readable by a non-WebP supporting browser.

Is there a way to use webpjs to convert the base64 webp to a png or jpg?


sample code snippet:

//load a webp, base64 encoded
$.ajax(
{
url: 'hippo_webp.txt',
success: function(data) { addImage(data) },
error: function(err) { console.log('no workie'); }
});

function addImage(data)
{
console.log('loaded image');
var img = new Image();
if (WebP_support)
img.src = "data:image/webp;base64," + data;
else
{
//????
}
document.getElementById('add_img').src = img.src;
}

James Zern

unread,
Sep 26, 2013, 6:04:38 AM9/26/13
to webp-d...@webmproject.org
Hi,


On Thursday, September 26, 2013 6:52:21 AM UTC+2, Teddy Garland wrote:
I am storing WebP images in my CDN to decrease storage size and bandwidth.

Great!
 
I would like to serve these images to all clients, occasionally via AJAX. I have no problem in IE or FF with an image that has an src preset in the HTML img tag.

My question is with loading an image in via AJAX. Images are stored as their base64 representation.

Just a note here, the base64 representation will be 4/3 the size of the webp.
 
When I set the src via JavaScript, the webpjs will not go back and convert the image to a format that is readable by a non-WebP supporting browser.

webpjs should be ok for lossy webp, though an earlier look at an emscripten based js decoder [1] showed that it was faster. That was more of a science project, but it might be worth exploring if you have a particular need.
 

Is there a way to use webpjs to convert the base64 webp to a png or jpg?


Canvas can be used for this [2][3]. Have a look at drawImage() and toDataURL().
 

sample code snippet:

//load a webp, base64 encoded
$.ajax(
{
url: 'hippo_webp.txt',
success: function(data) { addImage(data) },
error: function(err) { console.log('no workie'); }
});

function addImage(data)
{
console.log('loaded image');
var img = new Image();
if (WebP_support)
img.src = "data:image/webp;base64," + data;
else
{
//????
}
document.getElementById('add_img').src = img.src;
}

Teddy Garland

unread,
Sep 26, 2013, 2:43:53 PM9/26/13
to webp-d...@webmproject.org
James,

Thanks for your response. I'm not sure if we're on the same page though. I hadn't tried what you described, using the toDataUrl() to convert from png to webp, so I gave it a whirl. I found that it does not work within non-webp supported browsers, such as IE and Firefox. The code below immediately goes to 'onerror' and will not draw to the canvas in IE. It will throw on the drawImage() command because the image is not properly loaded. No problems in Chrome, the 2px webp is drawn in the top left corner of the canvas. 

I need my application to work in all browsers, and I think to achieve this I'll need to convert the webp base64 over to a png base64 before adding it to the canvas. I would think that this is exactly what webpjs does (and maybe your code too), but it does not appear do so when adding the image src via JavaScript. Is there a simple hook within webpjs (or equivalent) which would take in base64 of one image type and return base64 of another?

var canvas = document.getElementById('cvs');
var context = canvas.getContext('2d');
var webp_image = new Image();
webp_image.src = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
webp_image.onload = function() {
    context.drawImage(webp_image, 0, 0);
    console.log('drawing image');
};
webp_image.onerror = function()
{
    console.log('webp error!');
    context.drawImage(webp_image, 0, 0);
    console.log("that's cool, drawing image anyways");
};

Thank you

James Zern

unread,
Sep 27, 2013, 7:41:28 AM9/27/13
to webp-d...@webmproject.org


On Thursday, September 26, 2013 8:43:53 PM UTC+2, Teddy Garland wrote:
James,

Thanks for your response. I'm not sure if we're on the same page though. I hadn't tried what you described, using the toDataUrl() to convert from png to webp, so I gave it a whirl. I found that it does not work within non-webp supported browsers, such as IE and Firefox. The code below immediately goes to 'onerror' and will not draw to the canvas in IE. It will throw on the drawImage() command because the image is not properly loaded. No problems in Chrome, the 2px webp is drawn in the top left corner of the canvas. 

Right this is expected. I think this was my misunderstanding, I thought you were looking to convert the webp to something else after decoding.


I need my application to work in all browsers, and I think to achieve this I'll need to convert the webp base64 over to a png base64 before adding it to the canvas. I would think that this is exactly what webpjs does (and maybe your code too), but it does not appear do so when adding the image src via JavaScript.
 
Is there a simple hook within webpjs (or equivalent) which would take in base64 of one image type and return base64 of another?

Not that I know of, but both of the js decoder options write the RGB(A) to a canvas which can then be read back and then converted to the desired mime-type.

Teddy Garland

unread,
Sep 27, 2013, 7:00:15 PM9/27/13
to webp-d...@webmproject.org
I was able to pull this off with just a few modifications to webpjs. After downloading the demo page and following the images through each step, I found the last conversion was to take the data and convert to a byte array. So, I bypassed all the previous conversion methods and created a function to convert base64 to a byte array. That was all that was required.

James Zern

unread,
Sep 30, 2013, 8:35:55 AM9/30/13
to webp-d...@webmproject.org


On Saturday, September 28, 2013 1:00:15 AM UTC+2, Teddy Garland wrote:
I was able to pull this off with just a few modifications to webpjs. After downloading the demo page and following the images through each step, I found the last conversion was to take the data and convert to a byte array. So, I bypassed all the previous conversion methods and created a function to convert base64 to a byte array. That was all that was required.

Just so I'm clear, you're base64 encoding the decoded rgb data and using that as the img src data? What does your data uri look like in that case?

Teddy Garland

unread,
Oct 2, 2013, 12:04:18 AM10/2/13
to webp-d...@webmproject.org
Not quite, I never did explain the full version of this. The idea is to use HTML5 Web Storage as a cache to store image data to use as a video buffer. The Web Storage is a requires string-string key value pairs. So I when I deliver the base64 webp to Chrome (and Opera) that can go directly into the buffer, but all other browsers I have to go through the conversion to create a string. In the end, I replace the pixel data with a base64 encoded string, which can then be added to the buffer. It is decoded back to the pixel array before being added to the canvas, which serves as a video player. There's some added steps, but the decrease in storage size and bandwidth should make this worth while.
Reply all
Reply to author
Forward
0 new messages