Geuis
Geuis

Reputation: 42267

Using an svg image with inline data uri

I'm pretty sure this isn't possible, but before giving up I wanted to throw it out there.

Here's a fiddle, http://jsfiddle.net/sqszuzep/6/

<svg version="1.1" viewBox="0 0 2 1" width="100%">
    <image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/>
</svg>
<div id="bg" class="bg"></div>
<div id="bg2" class="bg"></div>

<h2>IE10/11</h2>
<div id="bg3" class="bg"></div>
<div id="bg4" class="bg"></div>

js:

// Chrome/Firefox/Safari
var x = encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><circle fill="#000000" stroke="#000000" stroke-width="20" cx="105" cy="105" r="90"></circle> <circle fill="none" stroke="#0000FF" stroke-width="10" cx="300" cy="105" r="90"></circle></svg>');

var y = encodeURIComponent('<svg version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/></svg>');

$(function () {
    $('#bg').css('background-image', 'url("data:image/svg+xml;utf8,'+ x +'")');
    $('#bg2').css('background-image', 'url("data:image/svg+xml;utf8,'+ y +'")');
});

// IE 10/11
// Chrome/Firefox/Safari
var x = btoa('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400"><circle fill="#000000" stroke="#000000" stroke-width="20" cx="105" cy="105" r="90"></circle> <circle fill="none" stroke="#0000FF" stroke-width="10" cx="300" cy="105" r="90"></circle></svg>');

var y = btoa('<svg version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="http://fillmurray.com/600/300" x="0" y="0" height="100%" width="100%"/></svg>');

$(function () {
    $('#bg3').css('background-image', 'url("data:image/svg+xml;base64,'+ x +'")');
    $('#bg4').css('background-image', 'url("data:image/svg+xml;base64,'+ y +'")');
});

Essentially I was attempting to use a svg image, encode the svg element and use it in css on an element. This works for vectors, but not for images loaded via svg.

I believe this pertains, https://bugs.webkit.org/show_bug.cgi?id=63548 saying that "Images are not allowed to load further resources".

What I see is that no browser supports this feature, or I'm doing something wrong.

It is possible to base64 encode image data and use that, as demonstrated in this fiddle I wrote: http://jsfiddle.net/N2n27/3/. On browsers that support svg filters (non-IE) this is a handy way to do blurring and other filter effects.

Am I missing something here?

Upvotes: 3

Views: 4195

Answers (1)

Robert Longson
Robert Longson

Reputation: 124059

There are two issues with the y version.

a) the svg element has no namespaces (it does in the x version) but in the y version it also needs the xlink namespace as the image href attribute is in the xlink namespace.

b) the image in the SVG is external.

A css background is an image itself so any SVG it references cannot load external resources. You therefore need to URI encode the inner image data and then uri encode the outer SVG (thereby doubly encoding the inner image data)

So you need something like this...

var y = encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 2 1" width="100%"><image xlink:href="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAA....

Which I've completed here for the Firefox/Chrome case

Upvotes: 1

Related Questions