Image Data URIs with PHP
If you troll page markup like me, you've no doubt seen the use of data URI's within image src attributes. Instead of providing a traditional address to the image, the image file data is base64-encoded and stuffed within the src attribute. Doing so saves a network request for each image, and if you're the paranoid type, can prevent exposure of directory paths. Since creating data URIs is incredibly easy, let me show you how to do it with PHP.
The PHP
Start by reading in the image using file_get_contents
(or any other PHP method you'd like), then convert the image to base64 using base64_encode
:
// A few settings $image = 'cricci.jpg'; // Read image path, convert to base64 encoding $imageData = base64_encode(file_get_contents($image)); // Format the image SRC: data:{mime};base64,{data}; $src = 'data: '.mime_content_type($image).';base64,'.$imageData; // Echo out a sample image echo '';
With the image data in base64 format, the last step is placing that data within the data URI format, including the image's MIME type. This would make for a good function:
function getDataURI($image, $mime = '') { return 'data: '.(function_exists('mime_content_type') ? mime_content_type($image) : $mime).';base64,'.base64_encode(file_get_contents($image)); }
The thing to remember is that IE7 and lower don't support data URIs, so keep that in mind if you're considering switching from image paths to data URIs!
You could write whole code for us :)
Btw. Good (Y)
Ups ! Sorry , didn’t see , internet too slow =)
Any chance you know of an existing wordpress plugin that could do the above encoding?
I don’t but I’ll see if I can find a HTML parser that can do it!
Hello,
Very Nice Post :)
But… how to protect other media like videos?
Thanks
Very interesting article. I love the helpful things you write about. Thanks and keep ’em coming.
I think this technique will not allow caching of images. What say about this?
And what about SEo aspect. I want my images to be crawled and indexed by google, so they appear in image search listings !
You would need to experiment; I don’t know that there’s a definitive answer for that.
DataURI’s are best used for things that you don’t want indexed – like icons/sprites/background images etc…
ie images that help you page look nice but are not related to content. If you are putting images as part of your blog or storytelling on your webpage, then by all means use http request to get the image from the server.
Wow, there’s no doubt this method can be useful but the resulting overall code ends up too messy!
Thanks anyway !
No so interesting according to me.
Doing so saves a network request for each image but only the number of
requests. With such a mechanism, no caching system can be used. All images
have to be downloaded again and again for each page view.
At the end, there is much more network data consummation and slowest page
display…
A good (and well thinked) caching policy is the best practice :) :)
It would cache with the web page which is totally appropriate in many cases, just set the cache headers in PHP.
PHP pages are made for dynamic content and data. For example, do you expect:
– the number of unread mail not to be updated on your favorite webmail
– to see your member area even if you’ve just logged out
– your basket not to be updated when you add/remove items
Dynamic content must not be cached
But even if you cache PHP pages, if the same picture appears on multiple pages, it will be cached multiple times…
I still think the best practice is a good cache policy (well tuned) for static content (picture, js, css, ….) and leave users request them only on first visit and on cache expire
Hint for anyone dealing with HTTPS: Internet Explorer 8 (and below, if you have a magic polyfill or something) considers data URIs to be unencrypted resources, thus triggering the famous “This page contains unsecure content” notice.
I never figured out a workaround, so if anyone has any tips I’m all ears!
Isn’t the
mime_content_type()
function deprecated?http://www.php.net/manual/en/function.mime-content-type.php
Good point. You could use this function or the suggested PEAR route; I stuck with this function because it’s probably the most supported and doesn’t require an external library.
mime_content_type()
is not (no longer?) deprecated and listed as part of PHP 7…Nice trick, I have used in my few websites, and would use in my new website jayjalaramext.com too,
But there is one limitations, IE8 and below do not render it, so would have to make IE specific stylesheet and use the image as regular source in it instead of uri 1.
There’s always one browser that doesn’t support it. Tusk /rolleyes
Good post though
Very nice! Is there a way we can get this to process multiple images at once?
There’s a class for handling PHP data URLs that I’ve been using for a project, http://www.flyingtophat.co.uk/blog/27/using-data-uris-in-php
I find it easier than calling numerous PHP functions.
Hey,
Thank you so much! This post was tremendously helpful! I was trying to find a way to embed images in PDF files with the DOMPDF library, and I came across your snippet of code which made my life much easier.. with one exception:
The DOMPDF lib choked on the space you put between
'data: '
and the mimetype. ie.data:* *mime/type.
. (their regex that parses data-uris wasn’t expecting a space there) Chrome seems to handle it fine, but if anyone runs into the same problem, I hope they find this comment and avoid pulling their hair out.Again, thanks so much for this code!
I double checked and it seems like the space present after
data:
is not standard (http://en.wikipedia.org/wiki/Data_URI_scheme#Format) .. so if you could take the space out of your code it’d lead fewer people astray.thanks!
(sorry for the double comment)
thanks,
mime_content_type()
is exactly what I needThank you so much. function
getDataURI
is very helpful.Is there any wordpress plugin for this? I tried the code but when my theme gets updated it removes the code.
Is there any way to “optimize” this image data so the URL is not 500 miles long?