O'Reilly

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!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

Incredible Demos

  • Hot Effect: MooTools Drag Opacity

    As you should already know, the best visual features of a website are usually held within the most subtle of details. One simple trick that usually makes a big different is the use of opacity and fading. Another awesome MooTools functionality is...

  • MooTools Clipboard Plugin

    The ability to place content into a user's clipboard can be extremely convenient for the user. Instead of clicking and dragging down what could be a lengthy document, the user can copy the contents of a specific area by a single click of a mouse....

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.

  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.

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

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...