dean.edwards.name/weblog/2005/06/base64-ie/

Base64 Encoded Images for Internet Explorer

This is a simple trick that I’m including in the next release of IE7. Mozilla and other browsers already support Base64 encoding of images. This gives web authors the ability to express image URLs in this geeky-looking (and therefore cool) way:

<img src="data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM/////
wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4ML
wWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw=="
alt="Base64 encoded image" width="150" height="150"/>

That ghastly mess will produce the following image in most decent browsers:

Base64 encoded image

Can’t wait to do it yourself now can you?

Internet Explorer does not support Base64 encoding of images so we will take advantage of PHP’s built-in base64_decode function. We will simply pass the Base64 data back to a PHP module which will then decode the data and return the appropriate image. Now that sounds complicated doesn’t it? Here is the required PHP code:

<?php
$data = split(";", $_SERVER["QUERY_STRING"]);
$type = $data[0];
$data = split(",", $data[1]);
header("Content-type: ".$type);
echo base64_decode($data[1]);
?>

That wasn’t so bad. Now we need a little bit of JavaScript to pass the Base64 data to the PHP module:

// a regular expression to test for Base64 data
var BASE64_DATA = /^data:.*;base64/i;
// path to the PHP module that will decode the encoded data
var base64Path = "/my/path/base64.php";
function fixBase64(img) {
	// check the image source
	if (BASE64_DATA.test(img.src)) {
		// pass the data to the PHP routine
		img.src = base64Path + "?" + img.src.slice(5);
	}
};
// fix images on page load
onload = function() {
	for (var i = 0; i < document.images.length; i++) {
		fixBase64(document.images[i]);
	}
};

Example: /my/base64-ie.html

In my next post I’ll show you a much sexier way of detecting and fixing the images. ;-)

Comments (64)

Leave a comment

Ah, blast, I thought you’d found a way of doing this without server support :) I spent a while playing with inline images some time ago.

  • Comment by: sil
  • Posted:

Cool, nice one. You’ll have to shorten your Acid2 odds now.

  • Comment by: Ivor Hewitt
  • Posted:

Stuart, I think it’s pretty much impossible without server side support. I’ve seen your article about inline images. I used to use XBMs in IE7 but IE6 XP SP2 no longer allows them.

See you on Saturday!

  • Comment by: -dean
  • Posted:

Got me fooled there for a while, though you had managed to hack ie to allow data uri:s for images. Unfortunately the usefulness of ‘inline images’ is greatly reduced if implemented on the server side. As that would be pretty much the same as requesting a static image. Really impressed with the rest of IE7 through.

  • Comment by: Emil
  • Posted:

There is a way of doing it without server support.

Write a base64 decoder, JPEG decoder, PNG decoder and GIF decoder in Javascript. Generate a span element with inline styling to display each pixel. Emulate the altered CSS behaviour for replaced elements vs non-replaced elements. Emulate the Image objects in Javascript and replace the DOM with a wrapper that substitutes placebo img elements where necessary. Add additional CSS rules that apply img {} rules to elements matching .img {}.

Evil, but theoretically possible.

  • Comment by: Jim
  • Posted:

Neat! I don’t see how Base64 images are useful, but this is still neat. But in the first PHP example, you should replace all double quotes with single quotes. It speeds up the code (albeit in milliseconds).

  • Comment by: Dante
  • Posted:

What about CSS url(), iframes, script and link elements?

I think there is limited support for data: using the object element in IE. Maybe this can be used in some way?

Saturday :’(

Neat! I don’t see how Base64 images are useful

Simple: it prevents extra HTTP requests to the server. For something like a 1*20px gradient background that’s about 80% of the network data.

  • Comment by: ant
  • Posted:

Thanks ant!

But wouldn’t all the extra text on the page be just as bad as another HTTP request?

  • Comment by: Dante
  • Posted:

Dante: The amount of data would still be roughly the same but the point is that by reducing the number of requests the actual time required to load the entire page would be less as each request introduces a latency.

Jim: Performing gif/png and jpeg decompression in javascript would be quite inefficient and slow, as I’m sure your fully aware of. On the other hand it might be realistic do something similar to what your proposing using an easier graphics format, such as rle encoded bitmaps.

  • Comment by: Emil
  • Posted:

Neat! I don’t see how Base64 images are useful

Simple: it prevents extra HTTP requests to the server. For something like a 1*20px gradient background that�s about 80% of the network data.

80%? I think that’s a bit high. In any case, it’s only a net win when you don’t use that image again. If you are using it for something like a page background, and the visitor clicks onto another page with the same background, they’ll download it again instead of using the external image out of their cache.

It’s more likely to be useful in one-off images like illustrations that are actually content, rather than re-usable non-content like background gradients.

It also has the side-effect of not being able to be embedded in somebody else’s page, assuming, of course, that you don’t provide the server-side emulation for Internet Explorer.

PS: Dean – nested blockquotes are broken in comments.

  • Comment by: Jim
  • Posted:

[...] RSS solution Base64 Encoded Images for Internet Explorer Some interesting development with [...]

I’m trying to get the above example using the base64.php module to work locally but IE is still not showing the image when I copy and paste it all.

I used the source from the example page, and for the base64.php file I just copied the above php code into notepad a saved as base64.php:

What am I doing wrong?

  • Comment by: Aaron
  • Posted:

Aaron – PHP will not work locally. You need to install it on a web server and run the code from there.

  • Comment by: -dean
  • Posted:

Dev Tip: Rounded Corner Generator

is there someone who can recode the base64 php to asp? maybe you can send me an e-mail… greetz… sven

  • Comment by: sven
  • Posted:

Haha, sven the optimist..

  • Comment by: Wouter van Nifterick
  • Posted:

Hey, I was looking at this recently. I think the major advantage is the reason AbiWord uses it – it finally makes HTML a reasonable document format by allowing embedding of objects. (BTW, I’m pretty sure this works for <object> tags too, thus allowing an arbitrary embedding scheme).

So people can exchange and save HTML documents, even idiot users, without losing any content. You embed the CSS and the binaries. It is perfect for any page on a site that you’d like folks to save and share.

I’d also like a non-server way to make it IE compatible. Even with server submission, it is still useful, so long as the folks sharing the doc have access to the web, since you can with a small bit of javascript and URL rewrite have a simple mechanism for one-off docs that doesn’t require folks to have uploaded the content to the server first. I agree it is still an inefficient hack though.

I was hoping Dean might have a way of doing it that lets one call some ActiveX magic to parse the page.

  • Comment by: derek
  • Posted:

Oh. And of course the 30% overhead of base64 isn’t that much of a problem, right? IE does Accept-Encoding gzip for mod_deflate, no?

  • Comment by: derek
  • Posted:

I tested IE on win2003sp1, it can handle GET requests of 2071 chars, no more. This was enough for captcha jpeg image 30×70.

  • Comment by: arty
  • Posted:

Hey Dean,

I’m having the same problem Aaron had with regards to saving the php code as a php file on my server. My server supports PHP and it still won’t work. Am I supposed to adding more to the base64.php code than what you have above? Because when I set the decode path to you’re specific path on your server, it works.

This is what I’m doing:

I took your PHP code in this article, copied it over to a new file and saved it a base64.php on my server. Then I copied the source from you base64_1e page and just changed the path to where the base64.php file on my server and it still won’t work.

Please tell me what I’m doing wrong.

  • Comment by: Kevin
  • Posted:

Its pretty cool how can I replace an image in IE with my own using java script?

  • Comment by: Raj
  • Posted:

To Wrap up the the approaches we have the following result:

- For the Php Solution either using Dean’s or there is an other using MHTML. Pros: simple

Cons:

(1) It only works on small image more or less of 2000 byte of Base64 (2) Require a round trip.

- For an other Php or ASP approach which we put the base64 code in side a Textarea of form to send to the server then wait for the return in the form of the temp.png file. Pros:A little more complex but it is still simple.

Cons:(1) Require a round trip.

(2) more work on the server side to create differnt image file every time other wise IE will take it form the cach, at the same time to manage the temp files

- For the HTMl approach either using Div or Table element of th HTML. We have the javascript to convert pixel by pixel directly from the base64. Theorectically it works?- Yes but No. Yes it work No it does not.

Pros: Not require the work from the server

Cons: (1) Complex; it may require a third party javascript (2) It does not work on complex and large image. IE Will screw you up when the total element goes about 5000 elements in a pages.

———-WE ARE DISCUSSING ONE MORE NEW BREAK-THRU? (not quitetly) APPROACH–

Down at our place we have javascrip to – Create Convert code and decode BMP, PNG, XBM file -Only at Client side- With that luxury it allow us to have this approach.

-Covert the base64 to XBM files – I means Files; not file each to use for one color only such as one for Blue and one for Haft Blue so on . . .

-For the container IMG we use the the IE’ mask filter to change the background to transparent and the foreground to the color of my choise such as BLUE. We also use other IE’s filter of gradient to have an array of color for one XBM – Not monochrome as many had said. - Put those containers one on top of the others. And it works.

-Said that the XBM is the bad format because of it SIZE- Not 100% true. As general term a XMB Hex which is “,0×78″ or “,0×6″ of 5 or four bytes (iclude the comma) to describe 8 bits. Roughly it take about more or less of 1.25 bit to describe one pixel which is not too bad. Beside it only stay in the memory for the brief period and free right after the image has summbitted. Be sid the fact that the broswer alway take the background of the XBM as transparent image. - Depend on number of color the way the color are arrange one an determine how many XBM file needed.

- As the fairness , business ethic, the amout on investment we have to put up not counting the risk we endure that we may loose everything. We are not able to have these codes vailable at the pubvlic domain. If you need it give me a note at; E P H I T R A N @ G M A I L . C O M – (Please take the space out)

Thanks

Phi

  • Comment by: Phi Tran
  • Posted:

Aaron and Kevin – I’ve solution for you. Try changing $_SERVER["REDIRECT_QUERY_STRING"] into $_SERVER["QUERY_STRING"] in the php code. This should help. If won’t try detecting how the query string is stored in yours php instance.

Greetz, Szymon

  • Comment by: Szymon
  • Posted:

This is a very cool trick. Finally got it working.

Quick question.

Does Firefox have any known bugs with image swapping base64 decoded images?

Works fine in ie6.

  • Comment by: dreaddy_mck
  • Posted:

[...] http://dean.edwards.name/weblog/2005/06/base64-ie/ [...]

This is a demonstration of embedding images in a self-contained HTML document in Internet Explorer: http://www.bennherrera.com/EmbeddedImage/

  • Comment by: Valentin
  • Posted:

hello ,I tried this code, but it seems that the query string is not getting passed to base64.php (i am running apache 2 on windows, php 4.4) I can load the data[1] value with an encoded string on the base64.php, and get an image to display, but it seems the image on the ie.html page is not being passed via img.src + “?” etc. from the java. I can put an alert(img.src) and see the full path and string from page, but it seems that info not getting to my base64.php page. Any tips??? copied your code more or less verbatim.

thanks for a good tip though.

eric

  • Comment by: Eric
  • Posted:

If a user tries to load the file by its self, why not give them an error? if(!empty($_SERVER[”QUERY_STRING”]) { // Your code… } else { die(“You cannot load the file by its self!”); }

  • Comment by: Joe
  • Posted:

So why doesn’t M$ implement this, anyway? It’s not like it would be hard for them to do.

  • Comment by: Andy
  • Posted:

This is exactly what I am looking for! But is there any way to do this in java instead of php?

  • Comment by: Melanie
  • Posted:

@Melanie – I don’t know. You need the Java equivalent of PHP‘s base64_decode.

  • Comment by: -dean
  • Posted:

[...] Theoretisch knnte man das Bild ja auch per Ajax-Response bekommen…BASE64_encoded! Dann weiss man auch das es ferig geladen ist…man muss dann nur den Src des Bildplatzhalters richtig updaten -> Dean Edwards: Base64 Encoded Images for Internet Explorer Ob das Sinn macht? Sollte man lieber document.image verwenden? Wer weiss…auf alle Flle knnte man sowas machen auch wenn ich es noch nie in "freier Wildbahn" gesehen habe BTW.: "Pixelmator" sieht ja wohl mal richtig schick aus! Ich freue mich drauf da ich ganz sicher nicht Adobes "ProfiSpyWare" Photoshop kaufen will/kann. so long, tecM0 __________________ "Programming is just like sex, one mistake and you have to support it for the rest of your life." [...]

[...] AW: dynamische bilder einbinden – Heute, 15:15 inline bilder kann eigentlich nur Mozilla, aber Dean Edwards: Base64 Encoded Images for Internet Explorer [...]

[...] Schade … Armer IE Mal sehen wie das der Dean in "IE7"-js einbauen will…also ich sehe ja schwarz [ Dean Edwards: Base64 Encoded Images for Internet Explorer ] [ /IE7/ ] T. __________________ "Programming is just like sex, one mistake and you have to support it for the rest of your life." [...]

doesn’t seem to work in the real ie7

  • Comment by: bob
  • Posted:

This encryption of images based on the argument of server requests is mute when you remember that the image is first refreshed from the local cache.

Image encryption comes into play when you need to transport an image in the body of an HTML based email and not want an external request to a server.

This is the primary method of how spammers get images past hosts like yahoo, msn, AOL, Lycos and so on.

So it’s 6 of 1 and half a dozen of the other, use encoded images in the right way or not at all.

  • Comment by: Mark
  • Posted:

We need embedded images in HTML eMails and who cares is spammers use it – at least they haven’t “bugged” you by doing this.

The fact that IE doesn’t support it is simply because IE is NOT a web browser – it’s a desktop portal for exploring the internet, not unlike AOL’s old atrocity.

But IE’s conditional blocks are a boon from M$ for us to single out their bugs – we can also use their bespoke COMMENT to encapsulate stuff for proper web browsers that we don’t wan’t IE to bother rendering.

So.. the problem of depositing embedded images into your html can be reduced to embedding for web browser and normal linking for IE.

More info: http://msdn2.microsoft.com/en-us/library/ms537512.aspx http://www.quirksmode.org/css/condcom.html

  • Comment by: Steve in Glasgow
  • Posted:

[...] Dean Edwards: Base64 Encoded Images for Internet Explorer [...]

[...] Dean Edwards: Base64 Encoded Images for Internet Explorer [...]

[...] The fix for base64 encoded images is no longer included [...]

[...] The fix for base64 encoded images is no longer included [...]

[...] Der Fix für base64 encodete Grafiken Teile und genieße Diese Icons verzweigen auf soziale Netzwerke bei denen Nutzer neue Inhalte finden und mit anderen teilen können. [...]

How did you get

R0lGODlhDwAPAKECAAAAzMzM///// wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4ML wWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==

that represent the image ?

  • Comment by: budhi
  • Posted:

The script near the beginning of this page uses a JavaScript regular expression but most developers will go glassy eyed when trying to understand regular expressions.

Anyone interested in learning about JavaScript regular expressions (and understanding what the script above is doing) might like to study the following page which shows developers how JavaScript regular expressions work.

http://www.web-wise-wizard.com/javascript-tutorials/javascript-regular-expressions-regexp.html

I encounter ‘unterminated String literal’ error while trying to pass base64 image into a web page..anyone can help?

  • Comment by: Nedave
  • Posted:

how can i store following code as an image??/ R0lGODlhDwAPAKECAAAAzMzM///// wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4ML wWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==

  • Comment by: ash
  • Posted:

I just can’t believe in the suggested solution for IE.

Are you trying to say tha download the encoded (base64) content, send it all back to server, decode, download the decoded (image) content and show it is reasonable?

C’mon… I bet you roam all day long with a backpack full of things you’ll never ever will use, huh?

  • Comment by: T1
  • Posted:

[...] http://www.greywyvern.com/code/php/binary2base64 http://danielmclaren.net/2008/03/embedding-base64-image-data-into-a-webpage http://dean.edwards.name/weblog/2005/06/base64-ie/ [...]

I’ve been reading this thread with a lot of interest because I’m trying to implement a captcha at my website. I’m using GD::SecurityImage from Perl to create the image. This works fine when it outputs to its own page of course. However, when I try to add it to an html page I realise I must use the techniques here to display it in that marvelous browser IE. So i’m using the PHP program above to convert the image and display it. That works too. However, when i want to print some html above and below the image, I’m getting the image displayed out as raw text data.

Can anyone help me with ideas please?

Here’s more info if it helps….

Basically, I’m doing the following in perl

use GD::SecurityImage backend => ‘Magick’;

print “Content-type: text/html\n\n”;

the javascript stuff to do the conversion, as per this thread…

Print “some html stuff”;

my($data, $mime, $rnd) = GD::SecurityImage ->new( width => 320, height => 100, ptsize => 40, lines => 3, thickness => 0.2, rndmax => 5, scramble => 1, send_ctobg => 1, bgcolor => ‘#009999′, font => ‘StayPuft.ttf’, )

->random ->create( qw/ ttf ec #0022AA #0066CC / ) ->particle(300, 1000) ->out;

Then i try to print out the image in an img tag;

<img src=”data:image/$mime;base64,$data” alt=”security image” width=”320″ height=”100″/>

But all I get is the html ok and then the raw image text. If I cut and paste some known good image text into the code then it works ok and displays the image nicely. So it seems to be a problem with the encoding of the $data out of GD::

Any ideas? I’ve spent way too long on this….

  • Comment by: Angus
  • Posted:

Oh, here are the first few characters of the image text that GD:: is giving me and that I’m sticking into the image tag….it looks much more complex than other examples I’ve seen…..maybe this is the issue?

GIF89a@ then a whole bunch of weird characters that the parser prevents e from putting into here….

  • Comment by: Angus
  • Posted:

I was able to convert a base64 image retrieved from a soap call to image but I want to save the image directly to a directory. How can save a base64 image as jpeg to a directory??

Actually, I can also save the base64 as string in the database,, problem is it is relatively long.

Help please! How can i convert the image then save it?! Thanks! ^_^

  • Comment by: saraness
  • Posted:

Hi Dean,

the problem with the js solution is, that there are visitors with deactivated javascript. What about serving different versions by server-sided browser-sniffing in combination with conditional-comments. If the client is an IE before 8 the images will not be embedded. If the browser “lies” and by sending a wrong user-agent, the conditional-comments include directives that override the embedded images in the stylesheet, hide IMG-Tags with base64-encoded image data and replaces them with ordinary linked images. I wrote about this stuff on my website but it`s in german. (i just started translating it in broken english…)

Regards, Alex

  • Comment by: alm
  • Posted:

Hi Dean,

Love your work but I think I should point out that you may want to sanitise the data passed to this script. :)

  • Comment by: David
  • Posted:

Actually the code worked in internet explorer

(img src=”data:image/gif;base64,R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==”alt=”Base64 encoded image” width=”150″ height=”150″/)

  • Comment by: joakim
  • Posted:

[...] them. Obviously, this affects the generated documents’ portability. Of course, I tried using Base64 encoded images; they were visible when I opened the document in a browser, but Word wasn’t able to display [...]

[...] du es auch base64 encodieren, du gibst es binär aus! -> PHP: base64_encode – Manual -> Dean Edwards: Base64 Encoded Images for Internet Explorer __________________ robo47.net – Blog, Codeschnipsel und mehr | Caching-Klassen und Opcode [...]

[...] found an interesting article by Dean Edwards, which suggested in IE <8 scenarios a request could be send back with base64 [...]

It’s also good to have these, so you can display an offline webpage (with imgs) without the need for an online server.

  • Comment by: Anonymous
  • Posted:

[...] Base64 Encoded Images for Internet Explorer [...]

[...] Base64 Encoded Images for Internet Explorer [...]

[...] Pour les détails techniques de la base64 je vous invite à lire l’article de Wikipédia concernant la base 64. Pour encoder ses images en base64, je vous conseille le service web suivant : http://www.motobit.com/util/base64-decoder-encoder.asp. Pour rendre Internet Explorer compatible avec la base64, je vous invite à lire l’excellent article de Dean Edwards : Base64 Encoded Images for Internet Explorer [...]

[...] my images in base64 and I also know, that IE 6 and 7 does not support data URLs. I’ve seen Dean Edward’s trick for IE 6 and 7 but it works only with PHP support. And I can’t use PHP, so this isn’t working for [...]

[...] for an alternative way to do it. after googleing about the issue i have found a good tutorial at http://dean.edwards.name/weblog/2005/06/base64-ie/ [...]

Leave A Comment

Line and paragraph breaks automatic, email address never displayed. Some HTML allowed.