[LEITFADEN] Base64-kodierte Bilder im Browser vorschauen
Fünf bewährte Wege, Base64-kodierte Bilder auf der Seite darzustellen – direkte src-Zuweisung, FileReader, Canvas, Blob-Konvertierung und Framework-spezifische Muster. Inklusive Debugging-Tipps.
// DIE 30-SEKUNDEN-ANTWORT
Wenn Sie eine Base64-kodierte Bildzeichenkette haben und sie einfach auf der Seite sehen möchten, ist der kürzeste Weg, sie als data:-URI an img.src zuzuweisen. Drei Zeilen JavaScript:
const img = new Image();
img.src = 'data:image/png;base64,' + base64String;
document.body.appendChild(img);
// If the string already starts with 'data:image/...;base64,'
// — just assign it directly without prepending anything:
img.src = base64StringWithDataUriPrefix;
// METHODE 1: img.src – DER DIREKTE ANSATZ
Jedes <img>-Element behandelt einen Daten-URI wie eine reguläre URL. Weisen Sie den URI an src zu, und der Browser übernimmt für Sie das Dekodieren, die Formaterkennung und das Rendern.
Das funktioniert für jedes Bildformat, das der Browser nativ unterstützt: PNG, JPEG, GIF (animiert und statisch), WebP, SVG, BMP, ICO. Die Base64-Zeichenkette kann von überall stammen – einer API-Antwort, dem localStorage, einer Zwischenablage-Einfügung, einer Datenbankzeile.
Der MIME-Typ im Daten-URI ist für ältere Browser und einige eingebettete WebViews relevant. Haben Sie nur eine rohe Base64-Nutzlast (ohne data:-Präfix) und kennen das Format nicht, können Sie entweder die magischen Bytes prüfen (siehe Methode 5) oder auf image/png als Standard zurückgreifen – die meisten Browser schnüffeln und erholen sich selbst dann, wenn der MIME-Typ falsch ist.
// Plain HTML — no JavaScript needed if the string is static
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="preview">
// Dynamic JavaScript — load from a variable, fetch, or input field
function renderBase64Image(base64, mimeType = 'image/png', containerId = 'preview') {
const container = document.getElementById(containerId);
const img = new Image();
img.onload = () => {
container.innerHTML = '';
container.appendChild(img);
};
img.onerror = () => {
container.textContent = 'Invalid image data';
};
// Tolerate both raw Base64 and full data: URIs
img.src = base64.startsWith('data:')
? base64
: `data:${mimeType};base64,${base64}`;
}
renderBase64Image(myBase64String, 'image/jpeg');
// METHODE 2: FILEREADER FÜR VOM BENUTZER HOCHGELADENE DATEIEN
Wenn der Benutzer ein Bild über <input type="file"> hochlädt, müssen Sie es nicht manuell in Base64 kodieren. FileReader.readAsDataURL() liefert Ihnen einen vollständigen Daten-URI, den Sie direkt in img.src ablegen können:
<input type="file" id="fileInput" accept="image/*">
<img id="preview" alt="">
<script>
document.getElementById('fileInput').addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
// event.target.result is a complete data URI
// e.g. 'data:image/png;base64,iVBORw0KGgo...'
document.getElementById('preview').src = event.target.result;
};
reader.onerror = () => {
console.error('FileReader failed:', reader.error);
};
reader.readAsDataURL(file);
});
</script>
// METHODE 3: CANVAS FÜR ERZEUGTE ODER MODIFIZIERTE BILDER
Wenn Sie ein Bild auf einem <canvas> zeichnen oder verarbeiten, exportiert canvas.toDataURL() das Ergebnis mit einem einzigen Aufruf als Daten-URI. Nützlich für: Diagramm-Screenshots, Unterschriftsflächen, QR-Codes, Wasserzeichen oder alles, was clientseitig erzeugt wurde und Sie als Bild anzeigen oder herunterladen möchten.
// 1. Draw on canvas
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#00FF41';
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = '#000';
ctx.font = '20px monospace';
ctx.fillText('Hello, Base64!', 20, 100);
// 2. Export to data URI
const pngDataURL = canvas.toDataURL('image/png');
// pngDataURL === 'data:image/png;base64,iVBORw0KGgo...'
// 3. Display directly
const img = new Image();
img.src = pngDataURL;
document.body.appendChild(img);
// JPEG with quality control (0–1)
const jpegDataURL = canvas.toDataURL('image/jpeg', 0.85);
// WebP if supported
const webpDataURL = canvas.toDataURL('image/webp', 0.9);
// METHODE 4: FETCH + BLOB FÜR ENTFERNTE BASE64-NUTZLASTEN
Ist die Base64-Nutzlast groß (über 50 KB) oder zeigen Sie sie häufig an, ist die Konvertierung in eine Blob-URL über URL.createObjectURL() speichereffizienter, als den vollständigen Daten-URI im DOM zu halten. Die Blob-URL ist kurz (blob:https://example.com/12345-abcde), kann widerrufen werden, sobald sie nicht mehr benötigt wird, und vermeidet den 33-prozentigen Base64-Overhead in DOM-Strings.
// Convert a Base64 string to a Blob, then to a blob: URL
function base64ToBlobURL(base64, mimeType = 'image/png') {
// Strip the data: prefix if present
const payload = base64.includes(',') ? base64.split(',')[1] : base64;
// Decode Base64 to binary string
const binary = atob(payload);
// Convert binary string to Uint8Array
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
// Wrap in a Blob and create an object URL
const blob = new Blob([bytes], { type: mimeType });
return URL.createObjectURL(blob);
}
// Usage
const blobURL = base64ToBlobURL(myBase64, 'image/jpeg');
const img = new Image();
img.src = blobURL;
document.body.appendChild(img);
// IMPORTANT: free the memory when you're done with the image
img.onload = () => URL.revokeObjectURL(blobURL);
// METHODE 5: FORMAT AUTOMATISCH AUS MAGISCHEN BYTES ERKENNEN
Erhalten Sie eine rohe Base64-Nutzlast (ohne data:-Präfix) und wissen nicht, ob es sich um PNG, JPEG, GIF oder WebP handelt, werfen Sie einen Blick auf die ersten dekodierten Bytes – jedes Format hat eine eindeutige Signatur.
function detectImageFormat(base64) {
// Look at the first ~12 characters of the Base64 string
const head = base64.replace(/^data:[^,]+,/, '').slice(0, 16);
if (head.startsWith('iVBORw0KGgo')) return 'image/png';
if (head.startsWith('/9j/')) return 'image/jpeg';
if (head.startsWith('R0lGOD')) return 'image/gif';
if (head.startsWith('UklGR')) return 'image/webp';
if (head.startsWith('PHN2Zy') ||
head.startsWith('PD94bWw')) return 'image/svg+xml';
if (head.startsWith('Qk')) return 'image/bmp';
if (head.startsWith('AAABAA')) return 'image/x-icon';
return 'application/octet-stream'; // unknown
}
// Build a correct data URI even when the user only gave us the payload
function toDataURI(base64) {
if (base64.startsWith('data:')) return base64; // already complete
const mime = detectImageFormat(base64);
return `data:${mime};base64,${base64}`;
}
// REACT – BASE64-BILDER IN KOMPONENTEN ANZEIGEN
Behandeln Sie den Daten-URI in React wie jede andere String-Prop. Memoisieren Sie die Konvertierung, falls sich die Eingabe selten ändert:
import { useMemo } from 'react';
function Base64Image({ base64, mimeType = 'image/png', alt }) {
const src = useMemo(() => {
if (!base64) return '';
return base64.startsWith('data:')
? base64
: `data:${mimeType};base64,${base64}`;
}, [base64, mimeType]);
if (!src) return <div>No image</div>;
return <img src={src} alt={alt} loading="lazy" />;
}
// Usage
<Base64Image
base64={apiResponse.avatar}
mimeType="image/jpeg"
alt="User avatar"
/>
// For large images, prefer blob URLs (Method 4) and useEffect for cleanup:
function LargeBase64Image({ base64 }) {
const [blobURL, setBlobURL] = useState('');
useEffect(() => {
const url = base64ToBlobURL(base64, 'image/png');
setBlobURL(url);
return () => URL.revokeObjectURL(url); // cleanup on unmount
}, [base64]);
return blobURL ? <img src={blobURL} alt="" /> : null;
}
// VUE 3 – BEISPIEL MIT DER COMPOSITION API
Gleiche Idee, Vue-Syntax:
<script setup>
import { computed } from 'vue';
const props = defineProps({
base64: String,
mimeType: { type: String, default: 'image/png' },
alt: { type: String, default: '' }
});
const src = computed(() => {
if (!props.base64) return '';
return props.base64.startsWith('data:')
? props.base64
: `data:${props.mimeType};base64,${props.base64}`;
});
</script>
<template>
<img v-if="src" :src="src" :alt="alt" loading="lazy" />
<div v-else>No image</div>
</template>
// SVELTE – REAKTIVE ANWEISUNG
<script>
export let base64 = '';
export let mimeType = 'image/png';
export let alt = '';
$: src = base64
? (base64.startsWith('data:') ? base64 : `data:${mimeType};base64,${base64}`)
: '';
</script>
{#if src}
<img {src} {alt} loading="lazy" />
{:else}
<div>No image</div>
{/if}
// FEHLERBEHANDLUNG – WAS BRICHT UND WARUM
Bild wird als kaputtes Symbol-Platzhalter geladen. Die Base64-Nutzlast ist abgeschnitten, enthält Leerzeichen mitten im String oder verwendet URL-sichere Zeichen (-_) innerhalb eines Standard-Daten-URIs. Entfernen Sie Leerraum mit str.replace(/\s+/g, ''); konvertieren Sie URL-sicher zurück in den Standard mit str.replace(/-/g, '+').replace(/_/g, '/'); und verifizieren Sie, dass die Länge korrekt ist (die Base64-Länge muss ein Vielfaches von 4 sein, mit korrekter Auffüllung durch =).
Bild rendert, aber im falschen Format. Das Präfix data:image/png;base64, sagt PNG, doch die tatsächlichen Bytes sind JPEG. Der Browser schnüffelt die magischen Bytes und rendert es trotzdem korrekt – einige Headless-Browser und eingebettete WebViews jedoch nicht. Verwenden Sie Methode 5, um das echte Format anhand der Bytes zu erkennen.
Bild ist riesig im DOM und die Seite fühlt sich langsam an. Eine 1 MB große Base64-Zeichenkette in einer React-Komponente wird bei jedem State-Update neu gerendert. Wechseln Sie auf eine blob:-URL (Methode 4) – das ist eine 50 Zeichen lange Zeichenkette im DOM, unabhängig von der Bildgröße.
Bild funktioniert in Chrome, aber nicht in Safari. Safari hat strengere CSP-Standards und lehnt Daten-URIs in einigen Kontexten ab (<a download>, Service-Worker-Fetches). Testen Sie in Safari und greifen Sie bei Bedarf auf eine blob:-URL zurück.
Die Base64-Zeichenkette selbst ist ungültig. Manchmal ist das „Base64“, das Sie erhalten, doppelt kodiert, hex-kodiert oder schlicht beschädigt. Fügen Sie es zuerst in unseren Base64-zu-Bild-Decoder ein, um zu bestätigen, dass es gültig ist, bevor Sie Ihren Code debuggen.
// PERFORMANCE: data:-URI VS. blob:-URL – EIN SCHNELLER BENCHMARK
Für ein 500 KB großes JPEG, das in <img> angezeigt wird:
• data:-URI in src: 668 KB Zeichenkette im DOM (33 % Base64-Overhead). Der Browser parst den URI, dekodiert Base64, dekodiert JPEG. Etwa 80 ms First Paint auf einem Mittelklasse-Laptop.
• blob:-URL via URL.createObjectURL: 56 Zeichen lange Zeichenkette im DOM. Der Browser holt das Blob aus dem Speicher, dekodiert JPEG. Etwa 40 ms First Paint. Rund 50 % Speicherersparnis.
Bei einem 5 KB großen Symbol ist der Unterschied unsichtbar – beide rendern in unter 5 ms. Fazit: unterhalb von etwa 50 KB nehmen Sie, was bequem ist. Darüber bevorzugen Sie Blob-URLs.
// IHRE VORSCHAU ISOLIERT TESTEN
Wenn Sie einen Fehler vermuten, isolieren Sie die Base64-Zeichenkette zuerst von Ihrem Anwendungscode. Drei schnelle Prüfungen:
1. In unser Online-Tool einfügen. Geben Sie die Zeichenkette in den Base64-zu-Bild-Konverter ein. Wird das Bild dort korrekt gerendert, sind die Daten in Ordnung und der Fehler steckt in Ihrem Code. Rendert es auch dort nicht, sind die Daten weiter oben im Datenfluss beschädigt.
2. Als URL in einem frischen Tab öffnen. Kopieren Sie den Daten-URI (inklusive Präfix data:image/png;base64,), fügen Sie ihn in einen neuen Browser-Tab ein und drücken Sie Enter. Moderne Browser zeigen das Bild direkt an. (Einige blockieren data: in der Adressleiste – verwenden Sie in diesem Fall den Inline-Test aus Schritt 1.)
3. Länge prüfen. Eine gültige Base64-Zeichenkette hat eine durch 4 teilbare Länge (nach Entfernen von Leerraum). Die Auffüllung (=) gleicht die Differenz aus: 0 bis 2 abschließende =-Zeichen. Ist Ihre Länge nicht durch 4 teilbar, ist die Zeichenkette abgeschnitten oder erweitert.
// Quick validation snippet
function looksLikeValidBase64(str) {
const cleaned = str.replace(/^data:[^,]+,/, '').replace(/\s+/g, '');
if (cleaned.length === 0) return false;
if (cleaned.length % 4 !== 0) return false;
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(cleaned)) return false;
return true;
}
// 30-SEKUNDEN-SPICKZETTEL
Am schnellsten: den Daten-URI an img.src zuweisen. Fertig.
Aus einem Datei-Upload: FileReader.readAsDataURL(file).
Aus einem Canvas: canvas.toDataURL('image/png').
Bei großen oder wiederholt verwendeten Bildern: in ein Blob umwandeln und URL.createObjectURL(blob) verwenden.
Unbekanntes Format: die magischen Bytes schnüffeln (iVBORw0KGgo = PNG, /9j/ = JPEG usw.), bevor Sie den Daten-URI bauen.
Debugging: zuerst in den Base64-zu-Bild-Konverter einfügen – damit klären Sie, ob die Daten das Problem sind.
Weiterführende Lektüre: Daten-URIs verstehen · Base64-Bildeinbettung · Base64 in JavaScript: Browser & Node