Explain Codes LogoExplain Codes Logo

How can I convert an image into Base64 string using JavaScript?

javascript
promises
async-await
base64
Alex KataevbyAlex Kataev·Jan 3, 2025
TLDR

To encode an image to a Base64 string, FileReader's readAsDataURL method is your trusty companion in JavaScript:

function toBase64(file, onSuccess) { let reader = new FileReader(); reader.onload = () => onSuccess(reader.result); reader.readAsDataURL(file); } document.querySelector('input[type="file"]').onchange = (e) => { toBase64(e.target.files[0], console.log); // Console: Becoming Base64... };

Above, toBase64 does exactly as its name implies, invoking onSuccess with the Base64 string once done.

Bypassing cross-origin restrictions

Ever run into cross-origin restrictions? When importing an image from a URL, make sure it has the correct CORS headers to avoid the headache of security exceptions. For a smoother sail in local development, live-server helps fetch image files without those pesky restrictions.

// "Fetch" the image, Bob Ross style fetch(url) .then(response => response.blob()) .then(blob => { /* convert to Base64 here... */ }) .catch(e => console.error('Looks like CORS laid the smackdown:', e));

Handling mega images

Processing giant-sized images is like wrestling a bear – it hits your performance hard. If you must convert these behemoths, consider blob objects and data streaming to avoid hogging memory, much like telling the bear to go play elsewhere. Combined with FileReader, the Fetch API helps keep those claws off your performance.

async function toBase64(url) { const response = await fetch(url); const blob = await response.blob(); return new Promise((resolve, reject) => { // Oh, look! It's our good friend FileReader again! const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.onerror = reject; reader.readAsDataURL(blob); }); }

And, of course, compress or resize before converting to cut down that bulky Base64 outcome.

Riding the wave of modern approaches

While FileReader enjoys widespread support, the cool kids – ahem, modern browsers – offer better APIs to tackle binary data. For slicker performance and compression, consider a blend of the fetch API and canvas methods:

async function fetchAndConvertToBase64(url) { const response = await fetch(url); const blob = await response.blob(); const canvas = document.createElement('canvas'); const dataURL = canvas.toDataURL(); return dataURL; }

It's worth noting that this comes in handy if you need to manipulate the image (crop, rotate, change format) prior to conversion.

Promising async patterns and overcoming errors

Embrace Promises or the stylish async/await pattern to handle the asynchronous nature of these APIs. Add error handling to prepare for network hiccups, file access permissions or when someone decides uploading their holiday slideshow is a good idea.

function toBase64(file) { return new Promise((resolve, reject) => { if (!file.type.match('image.*')) { reject(new Error('Dude, this ain\'t an image!')); } const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = error => reject(error); reader.readAsDataURL(file); }); }

This way, you're ready to handle anything the wild west of the web can throw at your code.

Encoding raw binary data

Sometimes, you need to encode raw binary data, not images. As though plucked straight from a Bond movie, btoa() is on-hand for encoding to Base64 format.

const binaryData = /* some raw binary data */ const base64 = btoa(binaryData); console.log(base64); // 'SGVsbG8gdGhlcmUh'

Keep in mind, btoa() prefers strings. For binary blobs, it's back to the File API.

Libraries and plugins to the rescue

Need more functionality or a simpler API? Don't reinvent the mousetrap! Third-party libraries or plugins offer advanced functionalities, with crowd favorites including blueimp-load-image or pica. Resize, rotate, change formats – let them handle the messy stuff!