Skip to content

Instantly share code, notes, and snippets.

@Potherca
Last active May 8, 2023 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Potherca/d756e81e1ceddae9ded9328b6ac835c9 to your computer and use it in GitHub Desktop.
Save Potherca/d756e81e1ceddae9ded9328b6ac835c9 to your computer and use it in GitHub Desktop.

It used to be hard to Base64 encode an image. Most often, a server-side component was used.

Nowadays, with FileReader readAsDataURL it can be easily done, 100% in the browser.

    const file = … // the contents of the image goes here

    const reader = new FileReader();

    reader.onload = (event) => {
      // And here you have the Base64 Encoded image!
      const base64EncodedImage = event.target.result;
    };

    reader.readAsDataURL(file);

A full, real-world example would look like this:

<form>
    <input accept="image/png, image/jpeg, image/svg+xml" name="file" required type="file" />
    <button>Convert!</button>
</form>
<script>
  document.querySelector('form').addEventListener('submit', (event) => {
    event.preventDefault();

    const file = event.target.file.files[0];

    const reader = new FileReader();

    reader.onload = (event) => {
      const base64EncodedImage = event.target.result;
      alert(base64EncodedImage);
    };

    reader.readAsDataURL(file);
  });
</script>

Live demonstration available at https://gist.pother.ca/d756e81e1ceddae9ded9328b6ac835c9/

<!doctype html>
<html lang="en">
<meta charset="UTF-8">
<title>Base64 Encode an image</title>
<link rel="icon" href="https://favicon.potherca.workers.dev/31" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/picnic">
<link rel="stylesheet" href="https://pother.ca/CssBase/css/created-by-potherca.css">
<link rel="stylesheet" href="https://gist.pother.ca/33b4d10024f56ba0610f8e70477687cb/copy-button.css">
<script async src="https://gist.pother.ca/33b4d10024f56ba0610f8e70477687cb/copy-button.js"></script>
<style>
.created-by {
padding: 0.5em;
text-align: center;
width: 100%;
}
.hidden {
display: none;
}
article {
background-color: #fff;
border-bottom-left-radius: 0.5em;
border-bottom-right-radius: 0.5em;
}
article > * {
max-width: 60rem;
margin: 0 auto;
}
body {
background-color: #def;
}
header p {
font-style: italic;
text-align: center;
}
input[type="file"], textarea {
height: 20vh;
}
pre {
display: block;
margin: 0.5em;
padding: 0.5em;
white-space: pre-wrap;
word-break: break-word;
}
textarea {
font-family: monospace;
font-size: 0.75em;
}
</style>
<article class="flex two-third-500 off-sixth-500">
<header class="full">
<h1>Convert an image to Base64 Encoded</h1>
<p>Submit an image to convert it to a Base64 encoded string</p>
</header>
<main class="full">
<form method="POST" enctype="multipart/form-data">
<fieldset>
<legend>File to convert</legend>
<input accept="image/png, image/jpeg, image/svg+xml" name="file" required type="file" />
<button class="half off-fourth">Upload</button>
</fieldset>
<fieldset class="hidden">
<legend>Result</legend>
<label>
<textarea readonly></textarea>
</label>
<button type="reset" class=" fourth pseudo">Reset</button>
<a data-js="copy" class="button half">Copy</a>
<a data-js="uri-encode" class="button fifth pseudo">URI Encode</a>
</fieldset>
</form>
</main>
</article>
<footer class="created-by">
<p>
Source of this page is available on
<a href="https://gist.github.com/Potherca/d756e81e1ceddae9ded9328b6ac835c9">Github</a>
under a <a rel="license" href="https://spdx.org/licenses/MPL-2.0.html"
>Mozilla Public License 2.0</a> &mdash; Created by <a href="https://pother.ca/" class="potherca">Potherca</a>
</p>
</footer>
<pre data-js="copy">
&lt;form&gt;
&lt;input accept="image/png, image/jpeg, image/svg+xml" name="file" required type="file" /&gt;
&lt;button&gt;Convert!&lt;/button&gt;
&lt;/form&gt;
&lt;script&gt;
document.querySelector('form').addEventListener('submit', (event) =&gt; {
event.preventDefault();
const file = event.target.file.files[0];
const reader = new FileReader();
reader.onload = (event) =&gt; {
const base64EncodedImage = event.target.result;
alert(base64EncodedImage);
};
reader.readAsDataURL(file);
});
&lt;/script&gt;
</pre>
<script>
function toggle() {
document.querySelectorAll('fieldset').forEach((fieldset) => {
fieldset.classList.toggle('hidden');
});
}
document.querySelector('[data-js="copy"]').addEventListener('click', (event) => {
const button = event.target;
const textarea = document.querySelector('textarea');
navigator.clipboard.writeText(textarea.value).then(() => {
button.innerText = 'Copied!';
setTimeout(() => {
button.innerText = 'Copy';
}, 1000);
});
})
document.querySelector('[data-js="uri-encode"]').addEventListener('click', (event) => {
const link = event.target;
const textarea = document.querySelector('textarea');
if (link.innerText === 'URI Decode') {
link.innerText = 'URI Encode';
textarea.value = decodeURIComponent(textarea.value);
} else {
link.innerText = 'URI Decode';
textarea.value = encodeURIComponent(textarea.value);
}
});
document.forms[0].addEventListener('reset', () => toggle());
document.forms[0].addEventListener('submit', (event) => {
event.preventDefault();
const form = event.target;
const file = form.file.files[0];
const reader = new FileReader();
reader.onload = (event) => {
form.querySelector('textarea').value = event.target.result;
toggle();
};
reader.readAsDataURL(file);
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment