Embedding Base64 Image Data into a Webpage

This is the second part of a tutorial for dynamically embedding a screenshot of a Flash movie into a webpage. In the previous section, we got image data out of Flash and into a Javascript variable. Now, we'll find out how to display that data using an <img> tag. If you want, you can skip ahead to copying the image to the clipboard.

And, no, this doesn't involve creating a table with 1 x 1 px cells in hundreds of rows and columns. (-;

Here's that demo from last time so you can see where we're going with this.

Flash

Image

Alright, so where we left off, we got the base64-encoded PNG data into a Javascript variable like so:

var screenshotBase64 = flashElem.getScreenshot();

Embedding the base64-encoded image in HTML

Now we've left the relatively sheltered environment provided by the Flash Player and we have to deal with some browser compatibility problems. Firefox provides an easy way to embed images dynamically in a webpage. You can use the data: URI scheme to put base64 (or other data) right into the src attribute of an image tag.

<img src="data:image/png;base64,iVBORw0KGgoAAAANS..." />

Base64 Images in Internet Explorer

IE is a little different. If you want to embed images right in the web page for Internet Explorer, you would use MHTML, which attaches the additional images as distinct and separate parts in the request. You can see an example of embedding images into a webpage using MHTML at Hedger Wang's website. It's easiest to figure out what's going on by looking at the PHP source code.

Since we're loading images dynamically this doesn't work for us so instead, what we'll do is write a short PHP script which accepts the encoded data and spits out the image. This gives us a URL where the image can be accessed directly, so it's like referring to any other image on the server. This is less than ideal, since it does involve a trip back to the server, but it works.

Here's the script which I got from Dean Edwards' post on displaying Base64-encoded images in IE.

<?php
/**
 * an example URL for viewing a base64-encoded image:
 * http://example.com/decode.php?image/png;base64,iVBORw0KGgoAAAANS...
 */
$data = split(";", $_SERVER["QUERY_STRING"]);
$type = $data[0];
$data = split(",", $data[1]);
header("Content-type: ".$type);
echo base64_decode($data[1]);
?>

So now, using this script, we can display the encoded image in Internet Explorer as well, using the following markup.

<img src="http://example.com/decode.php?image/png;base64,iVBORw..." />

The actual markup which embeds the image

To distinguish between Internet Explorer and, well, everyone else, I used conditional comments in the <head> like so:

<script type="text/javascript">
	function getImageSrc(base64Src)
	{ return base64Src; }
</script>
<!--[if gte IE 5]>

	<script type="text/javascript">
		function getImageSrc(base64Src)
		{ return "/decode_base64.php?" + base64Src.slice(5); }
	</script>
<![endif]-->

Now, I can easily set the src attribute of the <img> element.

// imageElem is the <img> tag that will display the screenshot
imageElem.src = getImageSrc("data:image/png;base64," + screenshotBase64);

And that's all it takes!

Note that the encoding used here is image/png but you can use other formats as well.

Embedding large images directly in HTML

There is a pretty significant problem with the way we worked around the Internet Explorer issue. If you're just embedding little icons then you don't have to worry, but when dealing with larger images, the base64 string can get too long. URLs have a limited length and it doesn't take a very large image to hit that boundary. In my brief tests a 100x100 pixel PNG was okay, but a 200x200 one was not. Note that this problem will only occur in IE since Firefox doesn't go back to the server at all.

To work around this problem I did something a little different. Instead of sending the base64 data to Javascript, I sent it directly to the server-side script in a POST request. The script saves the data to a temporary file and returns an ID for that file to Flash. Flash then calls it's ExternalInterface method, passing the file ID on to Javascript. Now, instead of setting the Image.src attribute to the decode_base64.php script above, you use a different script which takes the file ID as a parameter, sends the appropriate Content-Type header, retrieves the file and prints it to output, and finally, deletes the temporary file.

This is already a pretty unusual task so I won't post the howto for that, but if you'd like to hear more about that solution, give me a shout. In the third and last part of this little tutorial, we're going to copying the screenshot to the clipboard.

Comments

Lord Vader says, "It is possible to use"
Lord Vader's picture

It is possible to use Javascript only? If I use php, I have some trouble with URI-length for bigger images.
Request-URI Too Large" And I would like to see my images in offline mode.

daniel says, "Embedding large base64 images"
daniel's picture

@Lord Vader

I don't think this is possible only with Javascript. If you're having problems with the URI being too long, one solution is the implementation described under "Embedding large images directly in HTML" above. This sends the data in a POST request so it's not subject to the URI length limit.

Jonas Follesø says, "Data type and size of Base64 string"
Jonas Follesø's picture

Hi,

You mention that there are some issues embedding large images directly in HTML. Are there any limitation in the size of the base64 string passed from flash to the browser? If so, do you know if this limitation is documented some where?

Cheers,
Jonas

daniel says, "Flash to Javascript param size limit"
daniel's picture

Hi Jonas,

If there is a size limit passing a string from Flash to Javascript I haven't encountered it. The problem only occurs when getting a really long URL. And depending on the size of your image, the URL could end up getting very long:

http://example.com/decode.php?image/png;base64,iVBORw0KGgoAAAANS...

Hope that helps.

daniel says, "Large Images and Long URIs"
daniel's picture

Found a page that talks about the length-limitations of URLs. In case you were wondering.

Thanks to Pete Warden.

Jonas Follesø says, "Sweet"
Jonas Follesø's picture

Thanks for the info Daniel.

I'm going to build on your technique and take it one step fourther by passing the Base64 data into Silverlight and decode the PNG to play with the image. I'll drop you a comment when I have the post online.

Great work!

Cheers,
Jonas

iraqi boy says, "please help me"
iraqi boy's picture

hi boys
please can you send me the fill page of this code becouse its not work with me ,,please send the files to me by mail
thanks alot
iraq_ict@yahoo.com

Post new comment

The content of this field is kept private and will not be shown publicly.
If you have a Gravatar account, used to display your avatar.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You can enable syntax highlighting of source code with the following tags: <code>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

About

Daniel McLaren

Daniel is a Flash and Flex developer specializing in the art of information visualization.

Latest from SketchyD

Latest Drawing from SketchyD

This is the most recent drawing from my mobile sketch blog, SketchyD.com.

Recent comments