Skip to content

Instantly share code, notes, and snippets.

@hugolpz
Last active July 21, 2023 08:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hugolpz/7a2e24688591887f75c3 to your computer and use it in GitHub Desktop.
Save hugolpz/7a2e24688591887f75c3 to your computer and use it in GitHub Desktop.
Embedding raster image

This page is about embedding raster images into svg or html as data URI string. Data URI being base64 string, we first need to convert our image into base64 strings. There I explain how to do it server side and client side.

Convert png to base64 file

Given image.png as a valid image, let's creates a *.b64 copy as a text file containing a valid base64 text string.

openssl base64 -in image.png -out image.b64
echo $(cat image.b64)

Convert png to base64 variable

Alternatively, we can store it into a shell variable.

imgb64=$(cat image.png | openssl base64)
echo $imgb64

Image SVG element : linking and embedding syntaxes.

<img> XML elements usually use the href or xlink:href attribute to link up to an external file such :

<image xlink:href="image.png" width="960" height="500" class="bg-image"></image>

Embedding requires to store the whole raster image as a data URI string. This data URI is made up with meta data plus the image base64 string, as shown below:

<image xlink:href="data:image/png;base64,<long-b64-data-URI-string-here>" width="300" height="100" class="bg-image"></image>

into which we got to inject the $imgb64 string.

Server side approach

As I build an online service, I can leverage the strength of serverside openssl, NodeJS, JSdom, and D3js. My image.png is converted into image.b64 itself loaded via native NodeJS fs.readFileSync() into variable i64.

var i64 = fs.readFileSync('./image.b64');
svg.append("image")
  .attr("y","0")
  .attr("x","0")
  .attr("xlink:xlink:href", "data:image/png;base64,"+i64) // /!\
  .attr("width", width)
  .attr("height", height)
  .attr("class", "bg-image");

A double xlink:xlink:href or _:xlink:href is needed[1]. The reason is that d3js used to infers the xlink namespace from the href attribute, and so delete the first xlink[2]. When outputting standalone files, we do need xlink:href which is required by various graphic softwares, so let's put 2 of them, one will be delete, one will stay, so it finally works.

Similarly, broken xmlns (XML namespaces[3]) needs to be hand-restored within to the svg elements. Something such :

var svg = window.d3.select("body").append("svg")
	.attr(":xmlns","http://www.w3.org/2000/svg") // if not:  file does not appear to have any style information
	.attr(":xmlns:xlink","http://www.w3.org/1999/xlink") // if not: Namespace prefix xlink for href

I then print the whole using :

var svgheader = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
fs.writeFileSync('image.svg', svgheader + window.d3.select("body").html());

Client side approach

I formerly though to work within web-browsers with my image.png, .html page, and *.js script on client side. In this case, I add to the d3js .js script the following:

// Convert raster data into base64 string
var converterEngine = function (input) {
    var uInt8Array = new Uint8Array(input),
        i = uInt8Array.length;
    var biStr = []; //new Array(i);
    while (i--) {
        biStr[i] = String.fromCharCode(uInt8Array[i]);
    }
    var base64 = window.btoa(biStr.join(''));
    console.log("2. base64 produced >>> " + base64); // check conversion result
    return base64;
};

// Get the target raster file and convert it, return data
var getImageBase64 = function (url, callback) {
    // 1. Loading file from url:
    var xhr = new XMLHttpRequest(url);
    xhr.open('GET', url, true); 
    xhr.responseType = 'arraybuffer'; // <= important!
    xhr.callback = callback;
    xhr.onload = function (e) {
        if (this.status == 200) { // 2. When loaded, do:
            console.log("1:Loaded response >>> " + this.response); // print-check xhr response 
            var imgBase64 = converterEngine(this.response); // convert BLOB to base64
            this.callback(imgBase64); //execute callback function with data
        }
    };
    xhr.send();
};

//SVG DOM injection
getImageBase64('./image.png', function (data) {
    d3.selectAll("image")                             //select target
      .attr("href", "data:image/png;base64," + data); // replace href link by data URI, d3js + client handle the missing xlink
})

See also

Notes

[1]: Christophe Viau on xlink d3js hack/1/ /2/

[2]: Mike Bostock on xlink d3js management

[3]: D3js > Namespaces

[4]: Rabbits by Brad Ashburn, see gallery

_This page is about embedding raster images into svg or html as data URI string. Data URI being base64 string, we first need to convert our image into base64 strings. There I explain how to do it server side and client side._
### Convert png to base64 file
Given `image.png` as a valid image, let's creates a *.b64 copy as a text file containing a valid base64 text string.
```bash
openssl base64 -in image.png -out image.b64
echo $(cat image.b64)
```
### Convert png to base64 variable
Alternatively, we can store it into a shell variable.
```bash
imgb64=$(cat image.png | openssl base64)
echo $imgb64
```
### Image SVG element : linking and embedding syntaxes.
`<img>` XML elements usually use the `href` or `xlink:href` attribute to **link** up to an external file such :
```xml
<image xlink:href="image.png" width="960" height="500" class="bg-image"></image>
```
**Embedding** requires to store the whole raster image as a data URI string. This data URI is made up with meta data plus the image base64 string, as shown below:
```xml
<image xlink:href="data:image/png;base64,<long-b64-data-URI-string-here>" width="300" height="100" class="bg-image"></image>
```
into which we got to inject the `$imgb64` string.
### Server side approach
As I build an online service, I can leverage the strength of serverside `openssl`, NodeJS, JSdom, and D3js. My `image.png` is converted into `image.b64` itself loaded via native NodeJS [`fs.readFileSync()`](http://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback) into variable `i64`.
```javascript
var i64 = fs.readFileSync('./image.b64');
svg.append("image")
.attr("y","0")
.attr("x","0")
.attr("xlink:xlink:href", "data:image/png;base64,"+i64) // /!\
.attr("width", width)
.attr("height", height)
.attr("class", "bg-image");
```
A double `xlink:xlink:href` or `_:xlink:href` is needed[1]. The reason is that d3js used to infers the `xlink` namespace from the `href` attribute, and so delete the first `xlink`[2]. When outputting standalone files, we do need `xlink:href` which is required by various graphic softwares, so let's put 2 of them, one will be delete, one will stay, so it finally works.
Similarly, broken `xmlns` (XML namespaces[3]) needs to be hand-restored within to the svg elements. Something such :
```javascript
var svg = window.d3.select("body").append("svg")
.attr(":xmlns","http://www.w3.org/2000/svg") // if not: file does not appear to have any style information
.attr(":xmlns:xlink","http://www.w3.org/1999/xlink") // if not: Namespace prefix xlink for href
```
I then print the whole using :
```javascript
var svgheader = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
fs.writeFileSync('image.svg', svgheader + window.d3.select("body").html());
```
### Client side approach
I formerly though to work within web-browsers with my image.png, .html page, and *.js script on client side. In this case, I add to the d3js .js script the following:
```javascript
// Convert raster data into base64 string
var converterEngine = function (input) {
var uInt8Array = new Uint8Array(input),
i = uInt8Array.length;
var biStr = []; //new Array(i);
while (i--) {
biStr[i] = String.fromCharCode(uInt8Array[i]);
}
var base64 = window.btoa(biStr.join(''));
console.log("2. base64 produced >>> " + base64); // check conversion result
return base64;
};
// Get the target raster file and convert it, return data
var getImageBase64 = function (url, callback) {
// 1. Loading file from url:
var xhr = new XMLHttpRequest(url);
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer'; // <= important!
xhr.callback = callback;
xhr.onload = function (e) {
if (this.status == 200) { // 2. When loaded, do:
console.log("1:Loaded response >>> " + this.response); // print-check xhr response
var imgBase64 = converterEngine(this.response); // convert BLOB to base64
this.callback(imgBase64); //execute callback function with data
}
};
xhr.send();
};
//SVG DOM injection
getImageBase64('./image.png', function (data) {
d3.selectAll("image") //select target
.attr("href", "data:image/png;base64," + data); // replace href link by data URI, d3js + client handle the missing xlink
})
```
### See also
* [D3js: how to generate standalone SVG files? (Nodejs)](http://stackoverflow.com/a/19080981/1974961)
* [Embedding raster files into SVG via href="<data URI>"](http://stackoverflow.com/a/26595628/1974961) [jsfiddle/v96/](http://jsfiddle.net/hugolpz/xGUsu/96/)
* [D3js issue/Add raster images as embedded files via href="<data URI>"](https://github.com/mbostock/d3/issues/2095)
### Notes
[1]: [Christophe Viau](http://twitter.com/d3visualization) on [xlink d3js hack/1/](https://groups.google.com/d/msg/d3-js/4pOdrFpgjTo/24sTzQXJYAwJ) [/2/](https://groups.google.com/d/msg/d3-js/4pOdrFpgjTo/24sTzQXJYAwJ)
[2]: [Mike Bostock](http://twitter.com/mbostock) on [xlink d3js management](https://groups.google.com/d/msg/d3-js/4pOdrFpgjTo/v-iRcglaGUsJ)
[3]: [D3js > Namespaces](https://github.com/mbostock/d3/wiki/Namespaces)
[4]: Rabbits by [Brad Ashburn](https://twitter.com/epicvector), see [gallery](http://thenounproject.com/bashburn/)
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
GJe3ruuc56AOKu6GYdTuXNJET+iDpNbCpsmlG7eu6+wAuygYPy9NB11f6ipg+pvd
brfdbvG/TWcgPLuDJZn+Cs/HpmkO+LuYYbAEHYgQgpplLMtKkoT+NkkS6mJcLBYX
0gyEELiqDcOoRq8IIWhOBW+yfZHucJIkOJVZloVhSJ1Sk080ntXA7y4NTHKOThWk
xjQh2Z/CMAzDkIYOXdqCihYR+igeDod29Ze5ECxBhyOEqBbts227GonnOM5FDWt5
nlOjkOu6URRlWQYtQej+zuJzGNRa3sJqtZp8osuypJO7Xq9h164GCrH4vAK1qx65
ggdaOrtXt5pLD4ChsAQdCz2T1nKdgB1JiNayWCxYfA6Glhqvouv65QQYjf/imb0H
qg8DNJ67zrcLIWoLhV76pM5UYQk6AWVZep4nrShd1z3Pu6a7UQhBvbPSYDjydjxC
CCmo0jRNCPe49M613+9rK1iZpsmq563I83y/37eUNb4oaZpCUJLjOJ7nXU1+MxTO
B50SzP+Dpo83GcPxeEySBEdiWZbruuv1mmuUPAG0mJRhGK7rckVGhrkhLEEZhmEY
ZghcWZ5hGIZhhsASlGEYhmGGwBKUYRiGYYbAEpRhGIZhhvD/AGkbQrJ91A0MAAAA
AElFTkSuQmCC
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@Miyagi-Panda
Copy link

Cool thread, thanks

@Marius-hub
Copy link

Marius-hub commented May 14, 2021

Hey! I believe exporting it with a .svg extension from the start could help if that's what you're looking for. I tend to use editing apps to improve the quality before putting it in my code, and therefore, on my website, so the platform I use for that allows .svg files. I would recommend https://imglarger.com, as it enlarges images without losing the quality or the good resolution, which is a must when using CSS as styling language because it's important to have proper sizing. It can also retouch pictures, which I love. Oh, and by the way, it's really important to convert it and be sure it won't change resolution when it's enlarged.

@hugolpz
Copy link
Author

hugolpz commented May 15, 2021

@Marius-hub thanks for the lonk. But this tutorial aim to show how to programatically embed a raster into a svg as a data uri. So online app are not allowed in this workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment