Image Data URIs with PHP

By  on  

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!

Recent Features

  • By
    CSS @supports

    Feature detection via JavaScript is a client side best practice and for all the right reasons, but unfortunately that same functionality hasn't been available within CSS.  What we end up doing is repeating the same properties multiple times with each browser prefix.  Yuck.  Another thing we...

  • By
    Interview with a Pornhub Web Developer

    Regardless of your stance on pornography, it would be impossible to deny the massive impact the adult website industry has had on pushing the web forward. From pushing the browser's video limits to pushing ads through WebSocket so ad blockers don't detect them, you have...

Incredible Demos

Discussion

  1. Haris

    You could write whole code for us :)
    Btw. Good (Y)

  2. Haris

    Ups ! Sorry , didn’t see , internet too slow =)

  3. 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!

  4. Hello,

    Very Nice Post :)

    But… how to protect other media like videos?

    Thanks

  5. IronPatriotNY

    Very interesting article. I love the helpful things you write about. Thanks and keep ’em coming.

  6. I think this technique will not allow caching of images. What say about this?

  7. Lolki

    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.

  8. Wow, there’s no doubt this method can be useful but the resulting overall code ends up too messy!

    Thanks anyway !

  9. wAx

    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 :) :)

  10. It would cache with the web page which is totally appropriate in many cases, just set the cache headers in PHP.

  11. wAx

    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

  12. 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!

  13. Paul Sayre

    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.

    • Martijn

      mime_content_type() is not (no longer?) deprecated and listed as part of PHP 7…

  14. 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.

  15. There’s always one browser that doesn’t support it. Tusk /rolleyes

    Good post though

  16. George

    Very nice! Is there a way we can get this to process multiple images at once?

  17. Tom

    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.

  18. 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!

  19. 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)

  20. thanks, mime_content_type() is exactly what I need

  21. Thank you so much. function getDataURI is very helpful.

  22. Is there any wordpress plugin for this? I tried the code but when my theme gets updated it removes the code.

  23. Is there any way to “optimize” this image data so the URL is not 500 miles long?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!