How to turn an image into a data URI string in Node.js

May 13, 2023#node#how-to

A data URI string is a way of representing data as a text string that can be embedded directly into HTML or CSS. It has the format data:content/type;base64,encoded_data, where content/type is the MIME type of the data (such as image/png or image/jpeg) and encoded_data is the base64-encoded binary data of the image.

<img src="data:image/png;base64,iVBORw0KGgoAAA
ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4
//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU
5ErkJggg==" alt="Red dot" />

You can use data URI strings to include small files or binary data in your web pages without having to make separate HTTP requests for them. This can improve the performance and efficiency of your web pages, especially if you have many small images or icons that are used frequently. However, you should also be aware of some drawbacks of using data URI strings, such as:

  • They increase the size of your HTML or CSS files, which can affect the loading time and bandwidth usage of your web pages.
  • They are not cached by browsers, which means they have to be downloaded every time your web pages are loaded.
  • They are not supported by some older browsers, such as Internet Explorer 8 and below.
  • They can be used for malicious purposes, such as phishing or malware distribution.

Therefore, you should use data URI strings wisely and only for small and static files that are essential for your web pages. You should also consider using alternative techniques, such as sprites, fonts, SVGs, or WebP images, to optimize your web pages.

To convert an image to a data URI in nodejs, you can use one of the following methods:

  1. Use the built-in fs module to read the image file as a buffer and then convert it to a base64 string. You will also need to specify the image type manually or use a library like image-type to detect it automatically. For example:
const fs = require('fs')
const imageType = require('image-type')

const contents = fs.readFileSync('image.png')
const b64 = contents.toString('base64')
const type = imageType(contents)
console.log(`data:${type.mime};base64,${b64}`)
  1. Use a library like image-data-uri that can handle both local and remote images and automatically generate the data URI for you. For example:
const imageDataURI = require('image-data-uri')

imageDataURI.encodeFromURL('https://example.com/image.png')
  .then(dataURI => console.log(dataURI))

imageDataURI.encodeFromFile('./some-file.png')
  .then(dataURI => console.log(dataURI))
  1. Use a library like node-fetch and base64-stream to fetch an image from a URL and pipe it to a base64 encoder stream. For example:
const fetch = require('node-fetch')
const base64stream = require('base64-stream')

fetch('https://example.com/image.png')
  .then(res => {
    return new Promise((resolve, reject) => {
      let chunks = []
      let myStream = res.body.pipe(base64stream.encode())
      myStream.on('data', chunk => {
        chunks = chunks.concat(chunk)
      })
      myStream.on('end', () => {
        resolve(chunks.toString('base64'))
      })
    })
  })
  .then(b64 => console.log(`data:image/png;base64,${b64}`))