2

Can you combine these 2 images into one external file on this JS fiddle and link to them as images?

Something like

<img src="base64.html#img1" />
<img src="base64.html#img2" />

I did see this answer, but it provides no examples
Can multiple base64 documents be stored in a single file?


What about using a dot in the filename and somehow making the file think that it's a different filename, like base64.img1.html and somehow using a file-header to split them so its one file but different parts.


Okay, new idea .. what if there was a way to specify the charStart and charEnd? Imagine there were 2 base64 encoded files and then you call one like

base64.0-3214.html // for one file (like font.woff)
base64.3215-5673.html // for another file (like demo.jpg)
Community
  • 1
  • 1
Kirk Strobeck
  • 17,984
  • 20
  • 75
  • 114
  • I bet you probalbly can put multiple images in a base64 file but you won't be able to navigate to them using hashtags. It seems to me you're looking for a service of some sort that returns a different stream depending on a hashtag or another variable. – Marvin Brouwer Feb 07 '14 at 11:11
  • Sure .. I like the answers so far, but I still believe there's gotta be something out of the box on this one. Maybe a header that makes the browser think its different files? And you can add a filename as a separator or something .. – Kirk Strobeck Feb 07 '14 at 17:34
  • Bottom line is this is a great optimization when you only need 1 cacheable http request for a site. – Kirk Strobeck Feb 07 '14 at 17:35
  • 1
    There used to be a spec prepared by the people from Mozilla for Resource packages for HTML. AFAIK never implemented, probably discontinued. These would be ZIP files with manifest describing caching. Browser would load the package linked by `link` element and pull resources from there. Old browser would not know about it and would still send request for each resource separately. http://stackoverflow.com/q/4165098/2157640 I guess that the motivation to ask this question was saving multiple requests overhead, too. – Palec Feb 08 '14 at 23:55
  • 1
    Bundling more images in one file can be done with SVG images. http://stackoverflow.com/q/14630035/2157640 – Palec Feb 09 '14 at 00:06
  • Also you could be looking for [sprites](http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29). With CSS it is possible to use them in HTML. – Palec Feb 09 '14 at 00:08
  • Will the images be always one next to the other? If you only want to have parts of one image able to serve as links, use [image map](http://www.w3.org/TR/html5/embedded-content-0.html#image-map) in HTML. – Palec Feb 09 '14 at 00:13
  • Not just images, any filetypes – Kirk Strobeck Feb 09 '14 at 03:14
  • Thanks all! There were many great answers here, was not an easy choice. Still with there was a non-js approach, but I'll keep dreaming :P – Kirk Strobeck Feb 13 '14 at 15:32

7 Answers7

3

Data-uris, which is the key here, are strings more often than not encoded as base-64.

As they are strings you can concatenate them as any other string. However, you cannot set a concatenated (data-uri) string directly as image source.

When concatenating you need to use a separator character so you can split them at arrival before setting them as image sources.

You could have the following strings as base-64 encoded data-uris:

var img1 = 'data:...',
    img2 = 'data:...';

A concatenated version could look like this with for example $ as a separator char:

var conc = img1 + '$' + img2;

This string can now be sent over the net containing the two data-uris combined.

To split them again at arrival from server:

var conc = getDataString();   /// some function to get the string from server
var images = conc.split('$'); /// split the string on the $ char
var img1 = images[0];         /// first index contains first string etc.
var img2 = images[1];

/// set the image sources
document.getElementById('image1').src = img1;
document.getElementById('image2').src = img2;

This of course will require error checking and validation and so forth, but for the principle this is one way of doing this.

Note that you cannot automatically split them simply by referencing them as a link. The server could of course parse the link and provide the single data-uri needed - just as what would be typical to do. But if you want, as I understood your question, to get a single string from server representing two (or more) images then you need to manually split them at client side.

Note 2: base-64 encoded images are 33% larger than an original binary image + the data-uri header needed for the browser to be able to use it as source. The question is probably if there is any gain doing it this way or if the total cost of an extra request to server retrieving binary data would be less in total due to the base64 overhead. Just my 2 cents..

Hope this helps (and that I didn't misunderstood your question entirely).

3

It is possible to put all resources (JavaScript, CSS, fonts, images) together in one big (cacheable) JavaScript file. The file will look messy (because of some lengthy CSS and Base64 strings), but don't let that put you off; you can use code generation to compile the JavaScript file from its separate components (see below).

Demo: http://jsfiddle.net/PgdXd/

CSS

Put your entire stylesheet in a single string literal (do not forget to escape quotes and line breaks) and embed that inside a JavaScript statement that dynamically creates a style element.

$('head').append("<style> ......... </style>");

Note: I am using jQuery here, but plain JavaScript will do just as well.

The statement above may have no effect in older web browser versions. For alternatives, see: How to dynamically create CSS class in JavaScript and apply?

Fonts

Embed your Base64-encoded font files inside your stylesheet, as explained here: http://sosweetcreative.com/2613/font-face-and-base64-data-uri

@font-face {
    font-family: 'latoregular';
    src: url(data:application/x-font-woff;charset=utf-8;base64,........) format('woff');
    font-weight: normal;
    font-style: normal;
}

As shown earlier, this should be embedded within the JavaScript statement that holds your stylesheet:

$('head').append("<style> @font-face { font-family:'latoregular'; src: url(data:application/x-font-woff;charset=utf-8;base64,........) format('woff'); font-weight:normal; font-style:normal; } .... </style>");

Images

There are two flavors. Background images can be specified in the stylesheet, just like we did with fonts:

.logo1 { background-image: url(data:image/png;base64,.......); }

The second flavor are regular images. In the HTML file, use img tags with an empty src attribute.

<img alt="" src="" class="icon1" />

Use javascript to populate the src attribute. The entire Base64 string is a string literal embedded inside the JavaScript statement.

$('.icon1').attr('src', 'data:image/png;base64,.......');
$('.icon2').attr('src', 'data:image/png;base64,.......');

The CSS class determines which data belongs in which img tag(s). It is alright for a certain class to be unused in one or more HTML pages that will be including this JavaScript file. The Base64 string just gets passed around a bit; the same negligible overhead is involved in other JavaScript-based approaches.

Code generation

Here's a simple example using bash scripts. But feel free to use Perl or T4 or whatever language or tool you like instead.

gendatauri.sh: outputs a data URI; parameters are filename and (optionally) MIME type.

#!/bin/bash
echo "data:${2:-$(file -bi $1)};base64,$(base64 -w0 $1)"

genimgsrc.sh: generates the jQuery statement to populate the src attribute of <img> elements; parameter is filename.

#!/bin/bash
filename=$1
basename=${filename##*/}
classname=${basename%.*}
echo "\$('.$classname').attr('src','$(./gendatauri.sh $filename)');"

gencss.sh: your stylesheet; use $(./gendatauri.sh FILENAME [MIMETYPE]) to inject file data. Example:

#!/bin/bash
cat << EOF
@font-face {
    font-family: 'latoregular';
    src: url($(./gendatauri.sh latoregular.woff "application/x-font-woff;charset=utf-8")) format('woff');
    font-weight: normal;
    font-style: normal;
}
.logo1 {
    background-image: url($(./gendatauri.sh icon1.png));
}
EOF

genjs.sh: combines all the different components into a single JavaScript file. Example:

#!/bin/bash

# CSS, including fonts and background images
(
    echo '$("head").append("<style>\n'
    ./gencss.sh
    echo '\n</style>");'
) | tr '\n' ' '
echo

# images
./genimgsrc.sh icon1.png
./genimgsrc.sh icon2.png

# JavaScript
cat YourOwnFunctions.js

Run it and redirect its output to generate the final JavaScript file. Make sure the .png, .woff and other resource files are present when you do.

./genjs.sh > GeneratedJavaScriptFile.js

Included the JavaScript file in each HTML file:

<script src="GeneratedJavaScriptFile.js"></script>

Just for clarity: on the web server, you only need GeneratedJavaScriptFile.js and the .html files; the original resource files do not need to be present there.

Community
  • 1
  • 1
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
  • Still wishing there was a non-js solution, but thank you much! great answer. – Kirk Strobeck Feb 13 '14 at 15:31
  • @KirkStrobeck: The biggest reduction is in embedding the Base64-encoded resources (fonts and background images) in CSS. If you can live with one more HTTP request per page, and you don't mind using sprites, then you can do without the JavaScript hacks. – Ruud Helderman Feb 13 '14 at 16:16
1

It is not possible in pure HTML within the data URI specification. (http://en.wikipedia.org/wiki/Data_URI_scheme)

It is possible to use JavaScript to grab only a substring of the base64 data/document and set that as the img's src attribute, as the linked answer proposes.

I'm just not sure that it's worth the trouble to do it this way, it seems rather complicated for maybe a very small gain in loading time.


if you want to use it, one way to do it could be this (simple draft, no error handling, no fancy functions): in your HTML document:

<script type="text/javascript" src="base64file.js" />
....
<img id="image0" src="" />
....
<img id="image1" src="" />
....
<script type="text/javascript">
   var singleImages = allImages.split('$');
   document.getElementById('image0').src = 'data:image/png;base64,' + singleImages[0];
   document.getElementById('image1').src = 'data:image/png;base64,' + singleImages[1];
   ....
</script>

in your base64file.js:

allImages = 'abc... <- the base64 code for the first image
             $ <- split indicator that is not a part of the base64 character set
            cba.... <- the base64 code for the second image
            ';
cypherabe
  • 2,562
  • 1
  • 20
  • 35
  • didn't see Ken's answer while writing this, which is basically the same idea. should I delete my answer? – cypherabe Feb 07 '14 at 11:54
1

Put each base64-encoded picture in a file of its own, then use server-side code to insert the base-64 data inside the HTML page. The server will see three separate files, but the client (i.e. the web browser) is served one big file. Now you only have one big HTTP request for the HTML page together with the two pictures. If necessary, use mod_rewrite to make the web browser believe that it is a static cacheable HTML page rather than a server-side PHP/Perl/whatever page.

Simple PHP example (tested on Ubuntu 12.04):

<img src="data:image/png;base64,<?php readfile("image1.base64.txt"); ?>" />
<img src="data:image/png;base64,<?php readfile("image2.base64.txt"); ?>" />

Note: make sure the base64 files do not have a newline character at the end.

Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
  • @KirkStrobeck: Physically, the images _are_ in separate files; with _fopen wrappers_ enabled, they can even be files on a different web server. You just do not reveal this separation to the client. Is that a problem? Or is there something else I missed in your question? – Ruud Helderman Feb 07 '14 at 20:58
  • Think of 2 html files, both very short, and one external 500kb file that gets cached and is immediately available on both pages. – Kirk Strobeck Feb 09 '14 at 03:16
  • Good point. Sorry, this particular approach is less suitable for big pictures that appear on more than one page. – Ruud Helderman Feb 09 '14 at 11:07
1

Use an image array. This requires no javascript, only HTML and CSS.

First, use a graphics editor (e.g. GIMP) to stitch your pictures together into one single big picture.

image array

Then use CSS attributes (width, height, background-position) to crop the image on the fly. <img> does not support this, but background images do.

.iconarray
{
    display: block;
    background-image: url(iconarray.png);
    background-repeat: no-repeat;
}

.icon1
{
    width: 64px;
    height: 64px;
    background-position: 0px 0px;
}

.icon2
{
    width: 64px;
    height: 64px;
    background-position: 0px -64px;
}

Use the CSS classes in a <span>:

<span class="iconarray icon1"></span>
<span class="iconarray icon2"></span>

Demo: http://jsfiddle.net/rFTpL/

Kudos go to:

Community
  • 1
  • 1
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45
  • Right, that's pretty standard sprite usage .. thx for the answer, but I'm looking for all types of mixed content, not images alone. `css`, `js`, `fonts`, `images`, and more – Kirk Strobeck Feb 10 '14 at 03:13
  • Sorry, I wasn't aware of that requirement. But I like your idea, so I gave you one more answer which (like most other answers here) uses JavaScript, and covers it all: css, js, fonts, images, and anything else you can think of. – Ruud Helderman Feb 12 '14 at 11:33
1

I've a simple answer.

var data64imgs = ['data:image/png;base64,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', 'data:image/png;base64,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'];

$(function () {
    $('[data-index]').each(function () {
        $(this).attr("src",data64imgs[parseInt($(this).data("index"))]);
    });
});

Paste the above code in a separate JS file and reference it where you need it.

Do this:

<img data-index="0" />
<img data-index="1" />

Now automatically, the images will show up.

Here's the Demo

Note if you want additional imgs, then add it to the array and that's it , just use appropriate index.

Amit Joki
  • 58,320
  • 7
  • 77
  • 95
1

From what I understand, you wish to cache various type of resources (like a font, an image, etc.) using a single HTTP request.

So, here's my take on this using jQuery (you may opt for using vanilla JavaScript):

Firstly, you can store all your data-to-cache as string or Boolean or Number in a Associative Array in JavaScript and load this single file as shown below.

var ResourceLibrary = [];
ResourceLibrary["hello"] = "Hello World!";
ResourceLibrary["genderMale"] = true;
ResourceLibrary["username"] = "srvikram13";
ResourceLibrary["isDeveloper"] = true;
ResourceLibrary["firefox"] = "data:image/png;base64,iVBORw0KG...."
ResourceLibrary["chrome"] = "data:image/png;base64,iVBORw0KG...."

Now for every element that you wish to apply the cache data, you can give a custom attribute say-data-src as shown below.

<img src='#' data-src='resourceId-firefox' alt='firefox' />
<img src='#' data-src='resourceId-chrome' alt='chrome' />
<p data-src='resourceId-hello'></p><br>
<input id='username' data-src='resourceId-username'/><br>
<input type="radio" data-src="resourceId-genderMale" />Male<br>
<input type="checkbox" data-src="resourceId-isDeveloper" />Developer<br>

Now on document.ready (or onload if using vanilla JS) just loop through each element with this custom attribute; and apply the cached value based on the corresponding resourceId.

$(document).ready(function(){
    $("*").each(function(i, e){
        if($(e).attr("data-src") && $(e).attr("data-src").indexOf("resourceId-") != -1) {
            switch($(e).get(0).tagName) { // Add more case statements to handle various types of elements
                case "INPUT" : 
                    if(!$(e).attr("type")){
                        $(e).val(ResourceLibrary[$(e).attr("data-src").replace("resourceId-", "")]);
                        return;
                    }
                    switch($(e).attr("type").toLowerCase()) {
                        case "radio":
                        case "checkbox":
                            $(e).attr("checked", ResourceLibrary[$(e).attr("data-src").replace("resourceId-", "")])
                    }
                    return;
                case "IMG" :
                    $(e).attr("src", ResourceLibrary[$(e).attr("data-src").replace("resourceId-", "")]);
                    return;
                case "P" :
                    $(e).html(ResourceLibrary[$(e).attr("data-src").replace("resourceId-", "")]);
                   return;
                default:
                   return;
            }
        }
    });
});

Working Demo

Vikram Deshmukh
  • 12,304
  • 4
  • 36
  • 38