Menü

Werkzeuge durchsuchenÄnderungsprotokoll

zum Navigieren zum ÖffnenBeschreiben Sie das Problem, nicht das Tool

Konvertieren Sie ein PNG in JPEG

Konvertiert ein PNG in einem Basis-JPEG in Ihrem Browser, in einer von Ihnen gewählten Qualität und mit Transparenz in einer von Ihnen gewählten Farbe. Der PNG-Decoder und der JPEG-Encoder werden beide auf dieser Registerkarte ausgeführt, sodass dieselben Einstellungen dieselbe Datei ergeben, unabhängig davon, welchen Browser Sie verwenden, und nichts irgendwohin gesendet wird.

Jedes PNG, einschließlich 16-Bit-, Paletten- und Interlaced-Dateien. Es wird in dieser Registerkarte gelesen und niemals irgendwohin gesendet.

Die JPEG-Qualitätsskala reicht von 1 bis 100. Bei etwa 80 können die meisten Menschen den Unterschied nicht mehr erkennen.

Eine Hexadezimalfarbe wie #ffffff oder #fff. JPEG kann keine Transparenz speichern, daher werden zuerst transparente Pixel darauf gemalt.

JPEG-Größe
Die Größe der unten angebotenen Datei in Einheiten von 1.024 Byte.
PNG-Größe
Kleiner um
Abmessungen
Transparente Pixel

So funktioniert es

Was das bewirkt

Wandelt ein PNG in ein JPEG um, ohne dass es Ihren Computer verlässt, und stellt Ihnen die eine Frage, die jeder andere Konverter für Sie schlecht beantwortet: Welche Farbe sollen die transparenten Teile haben?

Diese Frage stellt sich, weil JPEG drei Farbkanäle und keine Transparenz speichert. Bei einem PNG mit durchsichtigem Hintergrund liegen unterhalb dieser Pixel immer noch Farbwerte vor, und in einer aus einem Designtool exportierten Datei sind sie fast immer Null. Wenn Sie den Alphakanal weglassen, ohne etwas anderes zu tun, werden die Nullen sichtbar – weshalb ein nachlässig konvertiertes Logo als weiße Markierung auf einem schwarzen Rechteck ankommt.

Die Methode

Hier gibt es zwei Codecs und keinen der Browser.

Der offensichtliche Weg, dies zu bauen, ist createImageBitmap in ein OffscreenCanvas und heraus durch convertToBlob. Es sind vier Zeilen und es wurde abgelehnt. Die HTML-Spezifikation behandelt das Qualitätsargument als Hinweis und überlässt die Zuordnung der Implementierung, sodass Qualität 0.8 in Chrome, Firefox und Safari eine andere Datei ist – eine andere Größe, andere Artefakte, manchmal eine andere Chroma-Unterabtastung. Eine Seite, deren Hauptanzeige „Ihre Datei ist jetzt 827 Bytes“ lautet, kann diese Zahl nicht haben, abhängig davon, welcher Browser geöffnet ist. Schlimmer noch: Ob convertToBlob die Transparenz auf Schwarz oder auf Weiß abflacht, hängt ebenfalls von der Engine ab und ist von außen nicht übersteuerbar. Daher werden sowohl der PNG-Decoder als auch der JPEG-Encoder gemäß den oben aufgeführten Spezifikationen ausgeschrieben, und die einzige beteiligte Plattform-API ist DecompressionStream für den zlib-Stream innerhalb des PNG – der Teil des Jobs, der eine einzige richtige Antwort hat.

Der Decoder ist der gewöhnliche: Überprüfen Sie die Signatur, durchlaufen Sie die Chunks, vergrößern Sie den IDAT-Stream und machen Sie dann die Zeilenfilter rückgängig. Dieser letzte Schritt ist der Grund dafür, dass ein PNG nicht in der falschen Reihenfolge dekodiert werden kann, da jede Zeile aus der darüber liegenden Zeile und dem Pixel links davon vorhergesagt wird und Paeth basierend auf der Verlaufsrichtung des Farbverlaufs zwischen drei Nachbarn auswählt. Interlaced-Dateien kommen in sieben Durchläufen mit zunehmender Auflösung an und werden wieder zu einem Bild zusammengesetzt, bevor etwas anderes passiert.

Dann kommt es auf die Abflachung an, auf die es ankommt. Jedes Pixel wird zu source × alpha + background × (1 − alpha), berechnet anhand der gespeicherten Werte. Bei diesen Werten handelt es sich um gammakodierte sRGB-Werte, daher handelt es sich hierbei nicht um die physikalisch korrekte Mischung. Wenn man es richtig macht, wirkt bei linearem Licht ein halbtransparentes Mittelgrau über Weiß ein paar Prozent heller als hier. Dies geschieht mit Absicht, da jede Browser-Leinwand und jeder Bildeditor auch in sRGB zusammengesetzt ist und eine isolierte Darstellung bedeuten würde, dass das JPEG nicht mehr mit dem PNG übereinstimmt, das Sie gerade betrachtet haben.

Der Encoder ist ein sequentielles Baseline-JPEG. Farben werden in Y, Cb und Cr mit den von JFIF angegebenen vollständigen BT.601-Koeffizienten konvertiert – die Studio-Variante erzeugt eine Datei, die in jedem Betrachter verwaschen aussieht und bei der Codeüberprüfung unsichtbar ist. Unterhalb von Qualität 90 werden die beiden Farbebenen mit einem Boxfilter im Verhältnis zwei zu eins in jede Richtung gemittelt und nicht punktuell abgetastet, da bei der Punktabtastung eines Rot-Weiß-Musters die Hälfte der Farbe weggeworfen wird und die falsche Hälfte erhalten bleibt. Jeder 8×8-Block durchläuft die diskrete Kosinustransformation, wird durch die für die gewählte Qualität skalierte Anhang-K-Quantisierungstabelle dividiert und gerundet; Blöcke, die über den rechten oder unteren Rand hinausragen, wiederholen das letzte echte Pixel, anstatt mit Grau aufzufüllen, sodass der Encoder keine Bits ausgibt, die einen Rand beschreiben, der nicht im Bild ist.

Vor dem Weiterlesen

Sie kodieren dasselbe PNG in JPEG mit der Qualität 0,8 über die eigene Leinwand des Browsers, in Chrome, in Firefox und in Safari. Was bekommst du?

  • Die HTML-Spezifikation nennt es einen Hinweis und überlässt die Zuordnung der Implementierung.

  • Ja: unterschiedliche Größen, unterschiedliche Artefakte, manchmal unterschiedliche Chroma-Unterabtastung.

  • Auch die Pixel unterscheiden sich. Qualität entscheidet über Quantisierung, die darüber entscheidet, was weggeworfen wird.

Drei verschiedene Dateien – unterschiedliche Größen, unterschiedliche Artefakte und manchmal unterschiedliche Chroma-Unterabtastung, da die Spezifikation das Qualitätsargument als Hinweis und nicht als Vertrag behandelt. Eine Seite, deren Hauptausgabe Ihre Datei ist, ist jetzt 827 Byte groß. Diese Zahl kann nicht davon abhängen, welcher Browser geöffnet ist. Schlimmer noch: Ob die Leinwand die Transparenz auf Schwarz oder Weiß reduziert, bleibt ebenfalls der Engine überlassen und kann von außen nicht geändert werden. Der PNG-Decoder und der JPEG-Encoder sind hier also beide gemäß ihren Spezifikationen geschrieben, und die einzige beteiligte Plattform-API ist DecompressionStream für den zlib-Stream innerhalb des PNG – der eine Teil des Jobs mit einer einzigen richtigen Antwort.

Das 64 x 64-Beispiel. Ein Viertel davon ist vollständig transparent, und jedes einzelne dieser Pixel wird auf dem ausgewählten Hintergrund zusammengesetzt, bevor ein einzelner Block codiert wird – da JPEG keinen Alphakanal hat, in den sie eingefügt werden könnten.
  • Undurchsichtige Pixel3.072
  • Transparent, gefüllt mit dem Hintergrund1.024

Ein gelungenes Beispiel

Ein 64 × 64 PNG: ein horizontaler Rot-Blau-Verlauf, wobei die sechzehn Spalten ganz links vollständig transparent sind und darunter Nullen gespeichert sind, was ein Exporteur schreibt. Auf einen #ffffff-Hintergrund konvertiert:

Quality 40    766 B
Quality 82    827 B
Quality 95    1.2 KB

Dimensions           64 × 64
Transparent pixels   25.0% of pixels, filled with #ffffff

Das sind die vom Panel ausgegebenen Werte, gerundet wie ein Dateimanager. Der Encoder schreibt genau 766, 827 und 1.271 Bytes, und es sind die Bytezahlen, die die Testdatei angibt. Wenn sich also der Encoder jemals ändert, ohne dass sich diese Seite mit ändert, schlägt der Build fehl.

Die zugrunde liegende Arithmetik wird anhand der Spezifikation und nicht anhand eines anderen Encoders überprüft: Die Quantisierungstabellen bei Qualität 50 müssen genau den veröffentlichten Anhang-K-Tabellen entsprechen, die vier Huffman-Tabellen müssen vollständige präfixfreie Codes sein, deren Symbolsätze genau denen entsprechen, die ein Koeffizient benötigen kann, und kein Literal 0xFF innerhalb der entropiecodierten Daten darf ungefüllt bleiben. Der Decoder wird umgekehrt, anhand von Pixeln überprüft – jeder Farbtyp und jede Bittiefe, die das Format zulässt, alle fünf Zeilenfilter und eine Interlaced-Datei, bei der behauptet wird, dass sie Byte für Byte das gleiche Bild wie die nicht-interlaced-Version von sich selbst erzeugt.

Was es nicht tut

Es übernimmt kein Farbmanagement. Ein ICC-Profil, ein Gammablock oder Chromatizitätsdaten im PNG werden weggelassen und das JPEG wird als einfaches sRGB geschrieben, sodass ein Foto mit großem Farbraum flacher aussieht als das Original.

Es schreibt nur Baseline-JPEG, nicht progressives, sodass eine große Datei von oben nach unten geladen wird, anstatt an Ort und Stelle zu schärfen. Da der CRC nicht für jeden PNG-Block überprüft wird, wird eine beschädigte Datei normalerweise als Dekomprimierungsfehler und nicht als Prüfsummenfehler angezeigt. Es gibt keine Möglichkeit, eine Zieldateigröße zu erreichen – Sie wählen eine Qualität und finden heraus, was das kostet. Die Größe wird nicht geändert, zugeschnitten oder gedreht, und die EXIF-Ausrichtung der PNG-Datei wird ignoriert. Die Dateien sind auf 32 MB und 40 Megapixel begrenzt, da sowohl das dekodierte Bild als auch die drei Farbebenen gleichzeitig im Speicher gehalten werden müssen.

Und da die Größe nicht geändert wird, wird aus einem großen PNG ein großes JPEG. Um auch die Größe eines Fotos zu ändern, gehen Sie zuerst so vor: Weniger Pixel werden besser komprimiert als die gleichen Pixel stärker komprimiert.

So wird es gemacht

  1. Lesen Sie die ausgewählte Datei auf dieser Registerkarte, überprüfen Sie die 8-Byte-PNG-Signatur und durchlaufen Sie dann die Chunk-Kette für IHDR, PLTE, tRNS, IDAT und pHYs.
  2. Dekomprimieren Sie die verketteten IDAT-Blöcke als einen Zlib-Stream, indem Sie den browsereigenen DecompressionStream anstelle eines gebündelten Inflaters verwenden.
  3. Machen Sie den zeilenspezifischen Filter rückgängig – „Keine“, „Unter“, „Aufwärts“, „Durchschnitt“ oder „Paeth“ – und bearbeiten Sie das Bild nach unten, da jede Zeile anhand der Zeile darüber und des Pixels links davon vorhergesagt wird.
  4. Erweitern Sie die Samples auf 8-Bit-RGBA, unabhängig vom Farbtyp und der Bittiefe der Datei, und setzen Sie die sieben Durchgänge zuerst neu zusammen, wenn das PNG interlaced ist.
  5. Fügen Sie jedes Pixel mithilfe seines Alphas zur ausgewählten Hintergrundfarbe zusammen, sodass ein transparentes Pixel diese Farbe annimmt und nicht die Farbe, die sich darunter befand.
  6. Konvertieren Sie in Y, Cb und Cr mit den vollständigen BT.601-Koeffizienten, die JFIF spezifiziert, und halbieren Sie die Auflösung der beiden Farbebenen mit einem Boxfilter, wenn 4:2:0 verwendet wird.
  7. Nehmen Sie die diskrete Kosinustransformation jedes 8x8-Blocks, dividieren Sie sie durch die für die gewählte Qualität skalierte Anhang-K-Quantisierungstabelle und runden Sie.
  8. Huffman-kodieren Sie die Koeffizienten mit den Annex-K-Tabellen, fügen Sie nach jedem Literal 0xFF ein Null-Byte ein und schreiben Sie die JFIF-Markierungssegmente um das Ergebnis.

Wovon es ausgeht

  • Die Transparenz wird auf die ausgewählte Farbe reduziert, bevor etwas anderes passiert, und die Mischung erfolgt in sRGB und nicht in linearem Licht. Das ist physikalisch nicht korrekt – ein halbtransparentes Pixel erscheint ein paar Prozent dunkler als es sollte –, aber es ist das, was ein Browser-Canvas und jeder Bildeditor tun, sodass das JPEG mit dem PNG übereinstimmt, das Sie betrachtet haben.
  • Qualität ist die Skala aus Anhang K der JPEG-Spezifikation, nicht die des Browsers. Die gleiche Zahl gibt hier in jedem Browser Byte für Byte dieselbe Datei an, sie stimmt jedoch nicht mit „Qualität 82“ in Photoshop oder GIMP überein, da diese jeweils von unterschiedlichen Tabellen ausgehen.
  • Unterhalb von Qualität 90 werden die beiden Farbkanäle in jeder Richtung mit halber Auflösung gespeichert. Auf einem Foto ist dies unsichtbar; Bei gesättigtem Text oder dünnen farbigen Linien zeigt es sich als Rand, weshalb die Einstellung auf 4:4:4 erzwungen werden kann.
  • Ein 16-Bit-PNG wird auf acht Bits reduziert, indem das High-Byte jedes Samples beibehalten wird. JPEG ist ein 8-Bit-Format, sodass das Low-Byte nirgendwo hingehen kann.
  • Farbprofile werden nicht übernommen. Ein iCCP-, GAMA- oder cHRM-Block im PNG wird ignoriert und das Ergebnis wird als einfaches sRGB geschrieben, sodass ein Bild mit großem Farbraum flacher aussieht als das Original.

Fragen

Wird mein PNG irgendwo hochgeladen?

Nein. Das PNG wird in diesem Browser-Tab gelesen und sowohl die Dekodierung als auch die Kodierung erfolgen in einem Worker auf Ihrem eigenen Computer. Es gibt keinen Server, an den es gesendet werden kann, und der automatische Test für diese Seite schlägt fehl, wenn eine Anfrage diese Site verlässt, während eine Datei geladen wird.

Warum wird mein transparenter Hintergrund in anderen Konvertern schwarz?

Da JPEG keinen Alphakanal hat, muss die Transparenz in eine echte Farbe umgewandelt werden, und die meisten Editoren belassen alles, was unter den transparenten Pixeln gespeichert war. Das ist normalerweise Null, was Schwarz ist. Die Farbwerte befinden sich immer noch im PNG – der Alphakanal war das einzige, was sie verdeckte. Wenn Sie den Hintergrund hier festlegen, werden sie übermalt, bevor etwas codiert wird.

Warum ist mein JPEG größer als das PNG?

Weil PNG genau das sehr gut kann, was JPEG schlecht ist. Flache Farben, scharfe Kanten, Screenshots und Strichzeichnungen werden mit einer Kosinustransformation wunderbar verlustfrei und schlecht komprimiert. Wenn die Zahl „kleiner um“ negativ ausfällt, lautet die ehrliche Antwort, dass dieses Bild ein PNG bleiben sollte. JPEG gewinnt bei Fotos, und zwar in der Regel deutlich.

Welche Qualität soll ich verwenden?

Ungefähr 80 für Bilder auf einer Webseite und 60, wenn ein Anhangslimit erreicht werden muss. Über 90 wächst die Datei schnell, obwohl kaum jemand den Unterschied sieht, und über 95 wächst sie besonders stark. Unterhalb von etwa 50 werden die 8×8-Blöcke in glatten Bereichen wie dem Himmel sichtbar.

Entspricht dies der Einstellung „Als JPEG speichern“ in der gleichen Qualität in Photoshop?

Nein, und das tun auch keine zwei Encoder. Qualität ist keine durch die JPEG-Spezifikation definierte Zahl; Dabei handelt es sich um eine Möglichkeit, die Quantisierungstabellen zu skalieren. Jeder Encoder skaliert anders und beginnt mit anderen Tabellen. Dieser verwendet die in Anhang K der Spezifikation veröffentlichte Skalierung, die einer gemeinsamen Referenz am nächsten kommt, und liefert in jedem Browser jedes Mal das gleiche Ergebnis.

Verarbeitet es 16-Bit-, Paletten- oder Interlaced-PNGs?

Ja, alle. Der Decoder deckt jeden Farbtyp und jede Bittiefe ab, die das Format zulässt – ein, zwei, vier, acht und sechzehn Bit, Graustufen, Echtfarben, Palette und beide mit einem Alphakanal – plus Adam7-Interlacing und alle fünf Zeilenfilter. Eine 16-Bit-Datei wird auf acht Bit reduziert, da JPEG keinen Platz für den Rest hat.

Quellen