Image to Base64, Explained
After reading this you will know how Base64 turns image bytes into text, how much larger the result gets, when a data URI helps a web page, and when it quietly hurts one.
What a data URI actually is
A Base64 data URI is a way to write the entire contents of an image as plain text, so you can paste it directly into HTML, CSS, or JSON instead of linking to a separate file. A tiny red dot PNG might look like this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR4nGP4z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC
The browser reads that string, decodes the text after the comma back into the original bytes, and displays the image. No network request, no second file. The whole picture travels inside the document.
The string has three parts. The prefix data: declares the scheme. The middle, image/png;base64, gives the MIME type and the encoding. Everything after the comma is the image, encoded as Base64 text.
When to embed and when to link
Embedding removes one HTTP request. For a single small icon repeated on every page, that saved round trip can matter. The tradeoff is size: Base64 text is about 33 percent larger than the raw file, and embedded data cannot be cached separately from the page that holds it.
A useful rule: embed assets under a few kilobytes, link to anything larger. A 40 byte tracking pixel becomes roughly 54 bytes of text, which is trivial. A 200 KB hero photo becomes roughly 267 KB of text stuffed into your HTML, downloaded fresh on every page load, and never cached on its own. That is a bad trade.
Inline the small things that appear everywhere: UI icons, a 1x1 spacer, a blurred placeholder shown while the real image loads. Keep large photographs and diagrams as separate files so the browser can cache them and load them in parallel.
The size formula and why it grows
Base64 packs 3 bytes of input into 4 printable characters. It reads the input 3 bytes at a time (24 bits), splits those 24 bits into four 6-bit groups, and maps each group to one character from a 64 symbol alphabet (A-Z, a-z, 0-9, plus + and /).
Here n is the number of input bytes and L is the number of Base64 characters produced. The ceiling handles inputs whose length is not a multiple of 3: the encoder pads the final group with = characters so the output length is always a multiple of 4.
The ratio L/n approaches 4/3 \approx 1.333 for large files. That is the 33 percent inflation. For a 3000 byte input you get exactly 4 \times 1000 = 4000 characters, a 33.3 percent increase. The full data URI is a little larger still, because the data:image/png;base64, prefix adds a fixed 22 characters.
Worked example: encoding a 1x1 pixel
The smallest useful PNG
Load the page with its defaults and encode a minimal 1x1 PNG. A valid one is 68 bytes on disk. Follow the count:
- Input size is n = 68 bytes.
- Group into threes: \lceil 68/3 \rceil = \lceil 22.67 \rceil = 23 groups.
- Each group yields 4 characters: L = 4 \times 23 = 92 characters.
- Since 68 = 3 \times 22 + 2, the last group has 2 leftover bytes, so the output ends in a single
=pad. - Add the prefix
data:image/png;base64,(22 characters). The full data URI is 92 + 22 = 114 characters.
Check the inflation: 92 encoded characters from 68 bytes is a factor of 92/68 \approx 1.353. Slightly above 1.333 because the file is small and the fixed rounding matters more. As files grow, the ratio settles toward 1.333.
How inflation behaves across file sizes
The overhead is not constant in percentage terms for tiny files, but it converges quickly. The table shows the encoded length and the ratio for several input sizes, ignoring the fixed prefix.
| Input bytes | Groups | Encoded chars | Ratio |
|---|---|---|---|
| 1 | 1 | 4 | 4.000 |
| 10 | 4 | 16 | 1.600 |
| 68 | 23 | 92 | 1.353 |
| 1000 | 334 | 1336 | 1.336 |
| 100000 | 33334 | 133336 | 1.333 |
See the tradeoff yourself
Decoding back to an image
Decoding reverses the map. The tool reads the MIME type from the prefix, strips the data:...;base64, header, and converts each group of 4 characters back into 3 bytes. The = padding tells the decoder how many bytes the final group really held: one = means 2 bytes, two = signs mean 1 byte.
Because the MIME type lives in the prefix, the decoder knows to save a image/png string as a .png file and an image/jpeg string as .jpg. If the prefix is missing or wrong, the bytes may still be valid but the file gets the wrong extension.
Common mistakes
The errors below cause most of the "why does my image not show" reports.
- Wrong MIME type
- Labeling a JPEG as
image/pngconfuses some viewers. The decoded bytes are correct, but the declared type is a lie the browser may or may not forgive. - Stray whitespace and line breaks
- Some encoders wrap Base64 at 76 characters per line. In an HTML attribute those newlines can break the value. Strip them or keep the string on one line.
- URL encoding confusion
- The standard Base64 alphabet uses
+and/, which have special meaning in URLs. Inside a data URI attribute this is fine, but if you paste the raw Base64 into a query string it can corrupt. Data URIs handle this correctly on their own. - Embedding large images
- A 500 KB photo as a data URI adds about 667 KB of text to your document and defeats browser caching. Keep it as a file.
Base64 is not encryption or compression. It makes binary data safe to store as text and grows the size by a third. Anyone can decode it instantly, so it protects nothing.
Related tools
If you need to change the actual image format before or after encoding, the Image Format Converter moves between PNG, JPEG, WebP, AVIF and others, which lets you shrink a file before you inline it. Photos straight off an iPhone often arrive as HEIC, so convert them first with the HEIC to JPEG Converter. For vector work, the SVG to PNG Rasterizer renders SVG at a fixed resolution, and the PNG to SVG Tracer goes the other way when you want a small icon to scale cleanly instead of being embedded as a fixed bitmap.
Frequently asked questions
Why is my Base64 image bigger than the original file?
Base64 encodes 3 bytes into 4 characters, a fixed 33 percent increase. A 9 KB PNG becomes about 12 KB of text. There is no way to avoid this while staying in Base64; it is the cost of representing binary data as printable characters.
Can I embed a data URI in CSS?
Yes. Write background-image: url("data:image/png;base64,..."). This works well for small repeating icons and sprites, and it saves one request per icon.
Does encoding lose image quality?
No. Base64 is lossless and reversible. The decoded bytes are identical to the original file, bit for bit. Quality loss only happens if you re-compress the image in a lossy format like JPEG, which is a separate step.
How large can a data URI be?
There is no strict limit in the spec, but browsers and tools apply practical caps, and large data URIs slow down parsing. Keeping each one under a few kilobytes avoids trouble and keeps your HTML readable.
Are my images uploaded anywhere when I use this tool?
No. The encoding and decoding run entirely in your browser. The image bytes never leave your machine.