Ratgeber

Base64-Bild komprimieren (warum Gzip meist scheitert)

So verkleinerst du Base64-Bilder über die dekodierten Pixel, verstehst die Grenzen von Gzip und erreichst in Browser-JavaScript ein Ziel von 100 KB.

Warum Base64 etwa 33,3% größer ist

Base64 ist Kodierung: Drei Bytes werden zu vier Zeichen. Exakt gilt 4 × ceil(n / 3); der Data-URL-Präfix kommt zusätzlich hinzu.

Drei Verarbeitungsketten

Bildbytes→Base64 ist standardkonform, aber größer. Base64→Gzip→Base64 verlangt zwei Rückschritte. Dekodieren→Bild optimieren→Base64 bleibt ein normales Bild für img src.

Warum Gzip nach erneuter Textkodierung wenig hilft

Das Gzip-Zwischenergebnis kann kleiner aussehen, doch erneutes Base64 und Gzip-Rahmen kosten Platz. Außerdem ist es Gzip statt JPEG, PNG oder WebP und nicht direkt darstellbar.

Bildformate sind bereits komprimiert

JPEG, PNG und WebP nutzen eigene Kompression. Praktische Einsparung kommt meist durch weniger Pixel, geringere verlustbehaftete Qualität, entfernte Metadaten oder ein passenderes Format.

Richtiges Browser-JavaScript

Prüfe Base64 und Magic Bytes, dekodiere mit ImageBitmap, zeichne auf eine begrenzte Canvas und kodiere mit toBlob. Produktionscode braucht Größenlimits, Animationsschutz, WebP-Erkennung und Schutz vor veralteten Tasks.

Kurzes Beispiel mit Browser-APIs

async function compressBase64Image(dataUrl, maxWidth = 1600, quality = 0.82) {
  const [header, payload] = dataUrl.split(',', 2);
  const mime = header.match(/^data:([^;]+);base64$/)?.[1];
  if (!mime || !/^image\/(png|jpeg|webp)$/.test(mime)) throw new Error('Unsupported image');

  const binary = atob(payload.replace(/\s+/g, ''));
  const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
  const bitmap = await createImageBitmap(new Blob([bytes], { type: mime }));
  try {
    const scale = Math.min(1, maxWidth / bitmap.width);
    const canvas = document.createElement('canvas');
    canvas.width = Math.max(1, Math.round(bitmap.width * scale));
    canvas.height = Math.max(1, Math.round(bitmap.height * scale));
    const context = canvas.getContext('2d');
    if (!context) throw new Error('Canvas 2D unavailable');
    context.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
    const blob = await new Promise((resolve) => canvas.toBlob(resolve, 'image/webp', quality));
    if (!blob) throw new Error('Encoding failed');
    const output = new Uint8Array(await blob.arrayBuffer());
    let outputBinary = '';
    for (let offset = 0; offset < output.length; offset += 0x8000) {
      outputBinary += String.fromCharCode(...output.subarray(offset, offset + 0x8000));
    }
    return `data:${blob.type};base64,${btoa(outputBinary)}`;
  } finally {
    bitmap.close();
  }
}

Auf 100 KB verkleinern

100 KB sind 102.400 Bildbytes. Suche JPEG/WebP-Qualität begrenzt binär; reicht das nicht, skaliere proportional mit sqrt(Ziel/Aktuell) und wiederhole nur wenige Runden.

Qualität, Abmessungen und Format

Qualität ändert den Codec, Skalierung entfernt Pixel. Fotos passen oft zu JPEG/WebP, Transparenz und Grafiken zu PNG/WebP. Vergleiche echte Ausgaben.

PNG-Transparenz und JPEG-Hintergrund

JPEG kennt kein Alpha. Behalte PNG/WebP oder verlange vor dem Abflachen eine ausdrücklich bestätigte Hintergrundfarbe.

GIF, animiertes WebP und SVG

Canvas erfasst meist nur einen Frame. GIF, animiertes WebP und ICO sollten abgelehnt werden; SVG benötigt einen eigenen Text-Optimierer.

Lokal bedeutet privater, nicht automatisch sicher

Kein Upload vermeidet Server-Speicherung, ersetzt aber keinen Malware-Scan. Gerät, Erweiterungen und Browser-Codecs bleiben Risiken.

Wann Base64 ungeeignet ist

Für große Bilder sind Blob URL, separate cachebare Dateien oder binärer Upload mit Blob/FormData/ArrayBuffer besser.

Häufige Fragen

Kann Base64 komprimiert werden?

Ja, aber allgemeine Kompression ergibt kein direkt verwendbares Bild-Base64.

Direkt in img src?

Nur wenn die dekodierten Daten ein Bild sind; Gzip muss erst entpackt werden.

Wie auf 100 KB?

Qualität begrenzt suchen und danach proportional skalieren.

Verliert das Bild Qualität?

Skalierung und verlustbehaftete Qualität können sie senken.

Warum 33% größer?

Drei Bytes werden mit vier Zeichen dargestellt.

Wird es hochgeladen?

Der Kompressor verarbeitet alles im Browser.

Gzip davor oder danach?

Nutze normale HTTP-Kompression um das Dokument, nicht Gzip innerhalb der Bild-Data-URL.

Standards und Browser-Referenzen