> base64 | decode | JPG <
// Decode Base64 strings and data URIs back to JPG / JPEG photos — EXIF preserved, instant preview, one-click download
Decoded JPEG will appear here
No Recompression
The JPEG bytes that come out of the decoder are bit-identical to what was encoded — same quality, same EXIF, same DCT coefficients.
Local Decode
Your Base64 string is decoded with atob() entirely in the browser. No upload. No server. No analytics on the payload.
Live Preview
See the decoded photo and its dimensions immediately — download as .jpg with one click.
// ABOUT BASE64 TO JPG
What This Tool Accepts
- >Data URI: data:image/jpeg;base64,/9j/4AAQSkZ…
- >Raw JPEG Base64 payload (starts with /9j/)
- >Base64 with embedded whitespace / line wraps
- >Standard RFC 4648 alphabet (+/, optional = padding)
- >URL-safe Base64 (-_) — auto-normalised on decode
- >Multi-part JPEGs (JFIF, EXIF, Adobe, SPIFF markers)
Common Use Cases
- >Recovering a photo from a JSON API response
- >Extracting a profile avatar from a database TEXT column
- >Decoding a CMS image field stored as a data URI
- >Reconstructing a photo from an email MIME part
- >Rendering a camera snapshot sent over WebSocket
- >Debugging a broken <img src="data:image/jpeg;base64,…"> tag
- >Offline-first apps that cache photos as Base64
How Base64 → JPG Decoding Works
The decoder strips any data URI prefix, normalises whitespace and URL-safe characters, then calls atob() to convert each 4-character Base64 group back into 3 binary bytes. The result is wrapped in a Blob with MIME type image/jpeg and previewed with an <img> tag. Because Base64 is a bijective binary-to-text transform, the output JPEG is bit-identical to the original — its SHA-256 hash matches, and no quality is lost.
Example JPEG Data URI:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/wAALCAABAAEBAREA/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAA/AKp//9k=
Performance & Compatibility
- >Decode is O(n) on payload length — handles 100 MB+ without issue
- >Uses native atob() + Uint8Array — no third-party libraries
- >Supports EXIF-rich JPEGs from every major camera maker
- >Works in Chrome, Firefox, Safari, Edge, and mobile browsers
- >Pinch-to-zoom preview on mobile devices
- >Downloads via Blob URL — no server round-trip
// HOW TO DECODE BASE64 TO JPG
Step 1: Paste
Paste the Base64 string or full data URI into the input field
Step 2: Decode
Click [DECODE] — the JPEG is rendered instantly
Step 3: Inspect
Check the photo, its dimensions, and file size before saving
Step 4: Download
Click [DOWNLOAD .jpg] to save a bit-identical JPEG to disk
// CODE EXAMPLES — BASE64 TO JPG
JavaScript (Browser)
// Decode Base64 → JPEG Blob → preview
const b64 = '/9j/4AAQSkZJRgAB...';
const bin = atob(b64);
const arr = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; i++) arr[i] = bin.charCodeAt(i);
const blob = new Blob([arr], { type: 'image/jpeg' });
document.getElementById('preview').src = URL.createObjectURL(blob);
Decode a raw Base64 JPEG payload, wrap in a Blob, and render with <img>. Data URIs can be set directly on src.
Node.js
const fs = require('fs');
const b64 = '/9j/4AAQSkZJRgAB...';
fs.writeFileSync('out.jpg', Buffer.from(b64, 'base64'));
Decode Base64 text to a JPEG file using Node's built-in Buffer.
Python
import base64
with open('out.jpg', 'wb') as f:
f.write(base64.b64decode('/9j/4AAQSkZJRgAB...'))
Standard library only — Base64 → JPEG bytes → file.
PHP
<?php
file_put_contents('out.jpg', base64_decode('/9j/4AAQSkZJRgAB...'));
One-liner using base64_decode() and file_put_contents().
Shell (macOS / Linux)
echo '/9j/4AAQSkZJRgAB...' | base64 -d > out.jpg
POSIX base64 -d reads the string from stdin and writes the JPEG to disk.
// FAQ — BASE64 TO JPG
Q: What is Base64 to JPG decoding?
A: It reverses a Base64-encoded JPEG back to its original binary form. The decoder reads 4 ASCII characters at a time from the Base64 string, looks them up in the RFC 4648 alphabet, and outputs 3 binary bytes per group. The resulting byte array is a complete, valid JPEG file — same DCT coefficients, same Huffman tables, same EXIF metadata, same quality as before encoding.
Q: How can I tell the Base64 string is really a JPEG?
A: Every JPEG starts with the two magic bytes FF D8 (Start-Of-Image). When those bytes are Base64-encoded, the first 4 characters are always /9j/. So any Base64 string that starts with /9j/4AAQ (JFIF header) or /9j/2wC (many smartphone cameras using Adobe APP14) is a JPEG. Other formats have different prefixes: iVBORw0KGgo for PNG, R0lGOD for GIF, UklGR for WebP.
Q: Can I decode a data URI directly?
A: Yes. If your string starts with data:image/jpeg;base64,, the decoder strips that prefix automatically and processes the payload. If you have only the raw Base64 portion, our tool detects the JPEG magic number (/9j/) and wraps the decoded bytes as image/jpeg for the preview. Whitespace, line breaks, and tabs are all removed before decoding, so you can paste a pretty-printed JSON value straight in.
Q: Does decoding reduce the quality of my JPEG?
A: No. Base64 decoding is a pure binary transform — each Base64 character maps deterministically to 6 bits, and 4 characters decode to 3 bytes. The JPEG bytes that come out are bit-identical to what was encoded, so the quality is whatever the original JPEG was saved at. A SHA-256 hash of the decoded file will match the hash of the original. If your decoded photo looks worse than expected, the quality loss happened when the JPEG was first saved, not during the Base64 round-trip.
Q: The decoded JPG is broken — what could be wrong?
A: Typical causes:
• Truncated string — the Base64 was clipped somewhere. A complete JPEG ends with FF D9 (End-Of-Image), which encodes to /9k= or 2Q== in Base64. If your string does not end in one of those patterns plus optional padding, it is incomplete.
• Double-encoded — the JPEG was Base64-encoded twice. Decode it again.
• URL-safe alphabet — if the string uses -_ instead of +/, some decoders reject it. Our tool normalises both.
• Actually a different format — the payload is PNG or WebP. Use our generic Base64 → Image decoder which auto-detects format.
Q: Is my EXIF metadata preserved after decoding?
A: Yes. The EXIF APP1 segment (camera model, GPS, date/time, lens, ISO, white balance, orientation, etc.) is part of the JPEG byte stream. Because Base64 is bit-for-bit reversible, every byte — including EXIF — is restored. If you need EXIF-free photos for privacy reasons, strip the metadata after decoding using a tool like exiftool -all= out.jpg or a canvas-based re-export in the browser.
Q: Can I decode Base64 to JPG in the terminal?
A: Yes. On macOS and Linux: echo '/9j/4AAQSkZJRgAB…' | base64 -d > out.jpg
(older macOS base64 uses -D.)
On Windows PowerShell: [IO.File]::WriteAllBytes('out.jpg', [Convert]::FromBase64String('/9j/4AAQSkZJRgAB…'))
If your input is a full data URI, pipe it through sed 's|^data:.*base64,||' first to strip the prefix.
Q: How big a Base64 JPG can I decode?
A: Up to the memory limit of your browser. A 100 MB decoded JPEG needs ~135 MB of Base64 text, which modern desktop browsers handle without issue. Mobile browsers are reliable up to ~40 MB. For extremely large photos (RAW-converted JPEG exports from medium-format cameras), consider server-side decoding: base64 -d photo.b64 > photo.jpg is far faster than a browser round-trip.
Q: Does the decoder work offline?
A: Yes, after the initial page load. All decoding uses built-in browser APIs (atob(), Uint8Array, Blob, URL.createObjectURL()), none of which require a network connection. You can confirm this by disabling your network and continuing to decode — the preview and download both keep working.
Q: Is the Base64 JPEG encrypted or private?
A: No. Base64 is an encoding, not encryption. Anyone with your Base64 string can decode it back to the original photo in milliseconds, and EXIF data (including GPS coordinates) comes along for the ride. If the JPEG contains sensitive information, encrypt it (AES-GCM, age, PGP) before applying Base64, and only ever transport the string over HTTPS.
Q: Is decoding client-side — does anything get uploaded?
A: Nothing is uploaded. Every step — strip prefix, normalise whitespace, call atob(), build the Blob, render the <img>, trigger the download — happens in your browser. Open the Network tab of your browser dev-tools while decoding and you will see zero outbound requests for your Base64 payload. This tool is safe for confidential screenshots, personal photos, and regulated data.
Q: How do I decode Base64 to JPG in production code?
A: In Node.js: fs.writeFileSync('out.jpg', Buffer.from(b64, 'base64')). In Python: open('out.jpg','wb').write(base64.b64decode(b64)). In Go: b, _ := base64.StdEncoding.DecodeString(b64); os.WriteFile("out.jpg", b, 0644). In Java: Files.write(Path.of("out.jpg"), Base64.getDecoder().decode(b64)). In Rust: std::fs::write("out.jpg", base64::decode(b64)?)?. In Ruby: File.binwrite('out.jpg', Base64.decode64(b64)). In PHP: file_put_contents('out.jpg', base64_decode($b64)).
Q: Base64 to JPG vs Base64 to PNG — which should I use?
A: Look at the prefix of the Base64 string. If it starts with /9j/, it is JPEG — use Base64 → JPG. If it starts with iVBORw0KGgo, it is PNG — use Base64 → PNG. You cannot force a JPEG decoder to emit PNG (or vice versa); the magic bytes tell the truth. When in doubt, use the generic decoder which detects the format automatically and saves with the right extension.