Hi, I'm Christoph, the developer of compress-or-die.com.
I hereby ask you to accept the cookies
of the self-hosted Matomo Tracking software which I use to analyze the traffic to this website.
You can revoke your consent at any time on the following page: Privacy policy.
Eine Analyse der Bild-Kompressions-Pipeline des Social-Networks Twitter.
Autor: Christoph Erdmann (@McSodbrenner) Letztes Update: 2022-12-21 18 Min. Lesezeit English version | Deutsche Version
Update 2022-12-21:
Durch den Austausch mit dem Illustrator und Senior Concept Artist David Blatt (@KOPF_STOFF) ist herausgekommen, dass es möglich ist, das Original-JPEG zu erhalten. Der Artikel wurde entsprechend erweitert.
Ich bin recht aktiv bei Twitter, und immer wieder treffe ich auf Tweets, in denen sich User über die miese Qualität ihrer geposteten Bilder nach der Kompression durch Twitter aufregen und an Twitter kein gutes Haar lassen.
Aber ist die Qualität wirklich so schlecht? Ist Twitter die Bild-Qualität wirklich egal? Versucht Twitter, um jeden Preis auf seinen Servern Speicherplatz zu sparen? Oder sind die User gar selbst schuld und haben ihre Bilder schon in schlechter Qualität hochgeladen?
Ich habe einmal genauer hingeschaut, was Twitter eigentlich mit euren Bildern in den Tweets macht. Die erstellten Bild-Dateien habe ich mit dem COD eigenen Analyse-Tool compress-or-die.com/analyze analysiert.
Tatsächlich gibt es keinen offiziellen Eintrag von seitens Twitter darüber, wie die Bilder eigentlich genau verarbeitet werden. Gefunden habe ich diesen Forums-Eintrag vom Ex-Twitter-Mitarbeiter Nolan O'Brien von Dezember 2018, der bis Januar 2020 aktualisiert wurde. Da dieser Artikel schon ein paar Jahre alt ist, werde ich die dort platzierten Aussagen überprüfen und natürlich auch darüber hinaus einiges testen, was dort eventuell (gewollt?) nicht erwähnt wurde.
Um testen zu können, wie die in Tweets hochgeladenen Bilder komprimiert werden, musste ich erstmal wissen, welche Bildgrößen von Twitter überhaupt erstellt werden. Um nicht überflüssigen Traffic zu erzeugen, liefert Twitter die Bilder nämlich nur in der jeweiligen Pixelgröße aus, die für den Client (also euren PC oder euer Smartphone) im Moment des Anschauens ausreichend ist. Damit ihr beim Surfen aber nicht unnötig warten müsst, werden diverse Pixelgrößen der Bilder direkt nach dem Erstellen des Tweets generiert. Aus Sicherheitsgründen werdet ihr übrigens niemals euer Original-Bild von Twitter abrufen können.
Durch Blick in die Twitter-API-Dokumentation erfährt man, dass es bestimmte festgelegte Größen für Bilder gibt. Diese tragen die Namen thumb, small, medium und large.
Mit diesen Namen kann man sich jetzt die gültigen Bild-URLs in der Art und Weise, wie es auch Twitter in seiner Oberfläche macht, zusammensetzen:
Allerdings ist mir beim Überprüfen meiner Twitter-Timeline im Desktop-Client aufgefallen, dass Twitter nicht nur diese Namen, sondern auch andere Namen wie z.B. 240x240 nutzt, welche in der API-Dokumentation gar nicht erwähnt werden.
Da aber der Wert 239x239 für den Parameter name wiederum nicht funktioniert, habe ich durch ein Script die gültigen Namen ermittelt. Hieraus ergaben sich letztendlich folgende Namen für Bilder, deren Qualität zu testen ist:
120x120
thumb (150x150)
240x240
360x360
small (680x680)
900x900
medium (1200x1200)
large (2048x2048)
4096x4096
Twitter erstellt also neun verschiedene Pixel-Größen von eurem Ursprungsbild. Alle Größen bis auf thumb werden unter Beibehaltung des Aspect Ratio herunterskaliert, um in die Außenmaße zu passen. Nur das thumb wird auf ein quadratisches Format zur Mitte hin zugeschnitten.
Hochskaliert wird niemals. Ladet ihr ein 1000×1000px großes Bild hoch, wird diese Größe auch für medium und large ausgespielt. Streng genommen kann es also zehn mögliche Größen geben.
Vermutlich ist euch bei den Bild-URLs oben aufgefallen, dass man auch das Dateiformat png oder jpg für den Parameter format einsetzen kann. Das stimmt und erzeugt auch tatsächlich das entsprechende Dateiformat, aber letztendlich sind wir davon abhängig, für welches Bild-Format sich Twitter beim Generieren der URLs in seiner Oberfläche entscheidet. Dennoch habe ich alle Möglichkeiten an Bildern getestet, die Twitter generieren kann: Also alle 18 Varianten.
Fun fact: Die Twitter-Kompressions-Pipeline kann auch webp-Bilder generieren, allerdings habe ich in der Twitter-Oberfläche noch nie gesehen, dass dieses auch genutzt wird. Ob das Feature nur aus Testgründen existiert (vielleicht als Reaktion auf diese Anfrage) oder ob Twitter mehr damit vor hat, konnte ich leider nicht in Erfahrung bringen.
Den Test habe ich mit einem kleinen Set aus eigenen durch zahlreiche Meta-Daten ergänzte JPG-, PNG-, GIF- und WebP-Bildern durchgeführt. Dabei habe ich natürlich die auf dieser Twitter-Hilfe-Seite erwähnten Upload-Beschränkungen beachtet, welche besagen, dass ein Bild nur bis zu 5 MB groß sein darf und ein GIF, JPG, oder PNG sein muss... was aber nicht vollständig den Tatsachen entspricht, da der Upload eines WebPs auch funktioniert, was auch auf dieser API-Docs-Seite bestätigt wird.
Mit dem Smartphone selbst fotografiertes JPG-Bild mit Meta-Daten wie z.B. GPS-Location-Daten, eingebettetem Thumbnail und Farbprofil, EXIF- und IPTC-Daten etc.
Eine kleinere Version des ersten Bildes, welches gedreht wurde, aber mit korrekten EXIF-Meta-Daten zur 'Orientation' ergänzt wurde. Die Browser drehen das Bild normalerweise richtig, so dass die Vorschau korrekt aussehen sollte.
Eine 4092px breite Version des ersten Bildes mit einer Qualität von 92, welches möglichst beim Tweeten erhalten werden soll.
Ein kleinere Version des ersten Bildes im WebP-Format.
Ein kleinere Version des ersten Bildes im PNG-Format (1000×748px).
Ein kleinere Version des ersten Bildes im PNG-Format (680×509px).
CMYK-JPG mit eingebettetem Farbprofil 'U.S. Web Coated (SWOP) v2'. Quelle: https://en.wikipedia.org/wiki/File:Channel_digital_image_RGB_color.jpg
Ein PNG mit einem Gamma-Wert von 100, welches den Erfolg einer Gamma-Korrektur selbständig anzeigen kann.
Ein JPG mit einem farbkanal-vertauschenden ICC-Profil.
Ein PNG mit einem farbkanal-vertauschenden ICC-Profil.
Außerdem kamen noch ein paar andere Testbilder zum Einsatz, um partiell spezielle Eigenheiten zu testen.
Die JPG-Qualität ist immer 85/85 (Luminanz/Chrominanz) unter Verwendung der Standard-JPG-Quantisierungstabellen (JPEG-Spezifikation Annex K).
Das Color-Subsampling wird immer auf 4:2:0 konvertiert.
Baseline-strukturierte Bilder werden immer zur Progressive-Struktur konvertiert.
Alle Meta-Daten wie Exif, IPTC o.ä. werden entfernt. Ein möglicherweise eingebettetes Farbprofil wird übernommen, wenn das Ausgabeformat dem Eingabeformat entspricht.
Das Bild wird (auch aus dem CMYK-Farbraum) in den sRGB-Farbraum konvertiert.
JPGs werden sauber anhand der EXIF-Meta-Orientation rotiert.
Es gibt hier allerdings eine wichtige Ausnahme. Hält man sich an die später noch erwähnte 5-Punkte-Regel beim Upload eines JPGs, sind die Merkmale diese:
Das Aussehen entspricht exakt den Eingangsdaten.
Das Color-Subsampling entspricht dem Ursprungsbild.
Baseline-strukturierte Bilder werden immer zur Progressive-Struktur konvertiert, was aber nicht die Darstellung verändert.
Alle Meta-Daten wie Exif, IPTC o.ä. werden entfernt. Ein möglicherweise eingebettetes Farbprofil wird übernommen.
Solltest du mit Begriffen wie "Quantisierungstabellen" oder "Color-Subsampling" nichts anfangen können, wirf gern mal einen Blick in meinen anderen Artikel JPG endlich verstehen.
Es wird ein 8- oder 24-Bit-PNG ausgegeben (abhängig vom Eingabeformat; wird später noch genauer beschrieben).
Alle Meta-Daten wie Exif, IPTC o.ä. bis auf den gAMA-Chunk (beinhaltet den Wert für die Gamma-Korrektur) werden entfernt. Ein möglicherweise eingebettetes Farbprofil wird übernommen, wenn das Ausgabeformat dem Eingabeformat entspricht.
Die Qualität der JPG-Dateien ist nicht so gut, wie die Zahlen der Quantisierungstabellen (nach den Standardtabellen Qualität 85 für Luminanz und Chrominanz) vermuten lässt. Beim Vergleich des Twitter-Resultats mit dem eines mit cjpeg aus dem libjpeg-turbo-Pakets erstellten JPGs erkennt man gut, wie vergleichsweise schlecht die Qualität der Twitter-Kompression ist.
Achtet einmal genau auf die Schärfe des Logos und des B auf dem blauen Hintergrund. Auch die Ausprägung der Artefakte um das G auf grünem Grund ist geringfügig stärker.
Das von Twitter erstellte JPG.
Das mit cjpeg erstellte JPG.
Vermutlich wurde das Bild wiederholt immer wieder ins JPG-Format konvertiert, was für die Qualität eines JPGs leider äußerst nachteilig ist, weil bei jedem Speichern die Artefakte des vorherigen Speicherns verstärkt werden.
Der JPG-Algorithmus weiß natürlich nichts von Artefakten und geht davon aus, dass die Artefakte, die durch die vorherige Konvertierung entstanden sind, zum Bild gehören. Er versucht daher, diese auch für eine spätere Darstellung zu komprimieren, was letztlich zu neuen Artefakten führt.
Diese mehrfache Komprimierung ist auf jeden Fall die größte Schwachstelle der Twitter-Kompressions-Pipeline und darf in dieser Ausprägung eigentlich niemals auftreten.
Für eine präzise Bildwiedergabe im Druck verwenden professionell arbeitende Kreative oft ICC-Farbprofile. Daher habe ich einmal ein Farbprofil-Testbild hochgeladen, welches nur bei der korrekten Verarbeitung des eingebetteten Farbprofils die Farben in der richtigen Reihenfolge zeigt, und zwar (R)ot, (G)rün und (B)lau.
Das Farbprofil wird jeweils nur in das Ausgabeformat übernommen, was auch als Eingabeformat verwendet wurde.
Das ist im Falle des JPGs kein Problem, weil aus einem JPG bei Twitter auch garantiert wieder ein JPG generiert wird. Im Falle des PNGs kann es ein Problem werden, wenn euer PNG nicht mehr in 900×900px passt und somit dem Twitter-internen-Format-Test unterzogen wird, der sich für die Ausgabe als JPG entscheiden kann. Zu dem Thema, wann Twitter sich aber für welches Bildformat entscheidet, kommen wir später noch im Detail.
Bei der Konvertierung eines CMYK-JPGs kann Twitter natürlich nicht das Farbprofil in das Ausgabeformat übernehmen, weil das Bild grundsätzlich in den RGB-Farbraum konvertiert wird. Das CMYK-Farbprofil wird bei der Konvertierung jedoch leider komplett ignoriert, was zu einem recht blassen Endergebnis führt.
Das eingebettete Farbprofil 'U.S. Web Coated (SWOP) v2' wird von Twitter ignoriert.
Zur Kontrolle der korrekten Verarbeitung einer Gamma-Korrektur verwende ich ein selbsterstelltes Bild mit einem übertrieben hohen Gamma-Wert von 100 (Normal ist 2,2).
Dieses zeigt "OK" an, wenn das Bild richtig dargestellt wird, oder "Broken", wenn die Gamma-Korrektur nicht korrekt durchgeführt wurde.
Sollte dir der Sinn oder die Funktionsweise des Gamma-Wertes nicht ganz klar sein, kann ich dir diese Seite empfehlen: Understanding Gamma Correction.
Übrigens rate ich bei so einem Test davon ab, die für Gamma-Tests verbreiteten Checkerboard-Bilder zu verwenden.
Also Bilder, die effektvoll zwei Bilder überlagern wie z.B. das relativ bekannte Apfel-Birnen-Bild:
Diese funktionieren dadurch, dass die Bildinhalte der beiden gemischten Bilder nur bei jeweils jedem zweiten Pixel angezeigt werden.
Skalliert man solche Bilder, erzeugt die Vermischung der Pixel ungewollte Ergebnisse und könnte fälschlicherweise für einen Fehler bei der Gamma-Korrektur gehalten werden.
Das hier sind die Ergebnisse der PNG-Konvertierungen:
Wie man deutlich sehen kann, werden die PNGs richtig dargestellt.
Beinhaltet das Ursprungsbild einen gAMA-Chunk (dieser enthält die Gamma-Informationen im PNG-Format), wird dieser Chunk von Twitter korrekterweise in das Ausgabe-PNG übernommen.
Die JPG-Dateien werden nach der Konvertierung durch Twitter falsch dargestellt.
Da Gamma-EXIF-Daten normalerweise von den wenigsten Programmen interpretiert werden, wäre die richtige Vorgehensweise gewesen, die Bild-Daten entsprechend der Eingangs-Gamma-Werte auf einen Gamma-Wert von 2,2 umzurechnen und keine Gamma-Meta-Daten in das Bild zu übernehmen.
Wie auch im Falle der problematischen Farbprofil-Verarbeitung bedeutet das hier ebenso, dass es ein Problem werden kann, wenn euer PNG nicht mehr in 900×900px passt und somit dem Twitter-internen-Format-Test unterzogen wird, der sich für die Ausgabe als JPG entscheiden kann.
Ist das Input-Bild ein GIF mit nur einem Frame, wird das Bild dennoch in ein 24-Bit- anstatt eines 8-Bit-PNGs konvertiert.
Das sorgt zwar nicht für einen sichtbaren Qualitätsverlust, allerdings könnte Twitter hier Speicherplatz sparen, da das GIF-Format laut Spezifikation eh nur 256 Farben unterstützt und somit die 8-Bit-Farbtiefe in jedem Fall gereicht hätte.
Da aber vermutlich vernachlässigbar wenige Twitter-Benutzer 1-Frame-GIFs hochladen werden, ist dieses Vorgehen absolut vertretbar.
Nachdem wir jetzt wissen, wie die Kompressions-Pipeline von Twitter funktioniert, ist als nächstes interessant, welches Bild Twitter denn an welcher Stelle einsetzt.
Die Ausgabe-Maße des ausgegebenen Bildes sind relativ einfach zu bestimmen. Twitter beachtet das Device Pixel Ratio und spielt deshalb z.B. bei einer angeforderten Breite von 415px und einem DPR von 2 das Bild in 900px Breite und nicht in 680px aus.
Viel interessanter ist jetzt aber, welches Bild-Format Twitter denn tatsächlich ausspielt, da das PNG-Format ja eher für Icons, Grafiken und Bilder mit viel gleichfarbigen Flächen und wenig Farben Sinn macht, während das JPG-Format das geeignetere Format für Fotografien ist.
Laut dem schon oben genannten Forums-Eintrag von 2020 arbeitet Twitter folgendermaßen:
Je nachdem, ob die intern erzeugte JPG-Version oder die PNG-Version kleiner ist, wird das entsprechende Format verwendet. Bei welchen Pixelmaßen die beiden konkurrierenden Bilder vergleichen werden, wird leider nicht erwähnt.
Auf einem mobilen Endgerät wie z.B. einem Smartphone werden übrigens die gleichen Bilder ausgespielt wie im Browser, wobei hier natürlich das vorher erwähnte Device Pixel Ratio eine größere Rolle spielt. Auch der Upload von mehreren Bildern in einem Tweet spielt keine Rolle. Jedes Bild unterliegt dabei den hier erwähnten Regeln.
Zusätzlich gibt es laut des Forum-Eintrags noch die Möglichkeit, die Original-Ansicht eines JPGs zu erhalten.
Beim Upload eines JPGs müssen dafür vier Punkte beachtet werden, welche ich um einen weiteren Punkt zu einer 5-Punkte-Regel ergänzt habe:
Das Bild muss in die Außenmaße von 4096×4096px passen.
Die Dateigröße des Bildes muss kleiner als 5MB sein.
Das Bild darf nicht durch eine EXIF meta-orientation gedreht sein.
Die Kompressionsrate muss mindestens 1 Pixel pro Byte erreichen.
Der von mir hinzugefügte Punkt: Das Bild muss in einem RGB-Farbraum vorliegen.
Werden diese fünf Punkte eingehalten, wird das JPG nicht neu komprimiert. Man bekommt also die Ansicht des Ursprungsbildes.
Der vierte Punkt ist dabei durchaus erklärungsbedürftig. Es besagt aber einfach nur, dass die Dateigröße in Bytes kleiner als das Produkt aus Höhe und Breite sein muss. Nehmen wir z.B. dieses Bild:
JPG mit den Maßen 4092×3062px und einer Dateigröße von 2,48 MB (2.484.348 Bytes).
Multipliziert man Höhe und Breite (also 4092×3062) ergibt das den Wert 12.529.704. Bleibt die Dateigröße in Bytes wie in diesem Beispiel (2.484.348) unter diesem Wert ist es möglich, die Original-Ansicht des Ursprungsbildes zu erhalten. In diesem Beispiel wurde das Ziel leicht erreicht, aber bei JPGs mit kleineren Dimensionen und JPG-Qualitätswerten größer als 95 kann es schnell vorkommen, dass diese Regel nicht mehr eingehalten wird.
Interessant bei Erfüllung dieser Regel ist auch, dass dieses Bild exklusiv in der Detailansicht (also nach Klick auf das Bild im Tweet) angezeigt wird. Hat man in der Breite z.B. nur 1200px im Browser zur Verfügung, würde trotzdem ein hochgeladenes 4000px breites Bild zur Anzeige verwendet. Bei Nicht-Erfüllung der Regel würde stattdessen die nächstgrößere Version des stark komprimierten Bildes ausgewählt, also large (2048×2048px).
Tatsächlich entsprechen die in dem Forums-Eintrag getätigten Aussagen auch heute noch der Arbeitsweise der Twitter-Kompressions-Pipeline.
Zu den darüber hinaus herausgefundenen Erkenntnissen kann ich sagen, dass die von Twitter verwendeten Arbeitsweisen und angewendeten Kompressions-Werte größtenteils in Ordnung und nachvollziehbar sind, so dass vernünftige Ergebnisse in den Tweets erzielt werden können, wenn die Regeln für das Ursprungsbild eingehalten werden. Verletzt man diese Regeln, wird die Bild-Qualität durch die angesprochene Mehrfach-Kompression allerdings recht mies.
Das ist auch der Knackpunkt bei der Sache: Dadurch, dass Twitter kaum offizielle Informationen darüber gibt, wie man seine Bilder hochzuladen hat und wie diese dann komprimiert und ausgespielt werden, werden viele User allein gelassen, was dann aus Unwissenheit und daraus resultierenden Upload-Fehlern letztlich in Frust gegenüber Twitter mündet. Ein simpler Forumseintrag von einem ehemaligen Mitarbeiter ist meiner Meinung nach einfach nicht genug für eine professionelle Kommunikation.
Folgende Tipps möchte ich euch gern für eure Bilder mit auf den Weg geben:
Habt ihr photographisches Bildmaterial, welches in der Detailansicht bestmöglich angezeigt werden soll, achtet auf die oben angesprochene 5-Punkte-Regel. Das Vorschau-Bild wird in diesem Fall aber auf jeden Fall unscharf.
Bilder, die lediglich der unterstützenden Visualisierung des Tweets dienen und deren Detail-Ansicht unwichtig ist, empfehle ich als sRGB-PNG in max. 900×900px hochzuladen, weil das Bild in diesem Fall niemals zum JPG konvertiert wird und somit gestochen scharf (da unkomprimiert) bleibt. Verwendet man als Ausgangsbild ein 8-Bit-PNG, ist zusätzlich die Größe in Pixeln unwichtig.
Achtet beim Upload eines PNGs mit photographischem Inhalt darauf, den Gamma-Wert vorher auf 2,2 umgerechnet zu haben und keine Farbprofile zu verwenden.
CMYK-Bildmaterial sollte nicht direkt hochgeladen werden, sondern vorher in den sRGB-Fabraum konvertiert werden.
Pro-Tipp in eigener Sache: compress-or-die.com arbeitet selbstverständlich mit einer funktionierenden Gamma-Korrektur, einer sauberen Farbprofil-Umwandlung in sRGB und der Berücksichtigung von CYMK-Profilen. Es bietet sich an, die für die Tweets geplanten Bilder einmal in Compress-Or-Die vorbereiten zu lassen.
Solltet ihr von diesen Resultaten abweichende Bilder bekommen, hat sich eventuell etwas bei der Twitter-Kompressions-Pipeline geändert. Dann würde ich mich über ein paar Zeilen freuen, damit ich den Artikel überarbeiten kann. Aber auch sonst freue ich mich über Kritik, Feedback und Lob in jeglicher Art.
Magst du diesen Artikel?
Dann wäre es doch klasse, ihn mit anderen zu teilen.
If you always wanted to know how the JPEG compression works under the hood I want to recommend this article to you. It was important to me to write an article that is reasonable for every level of understanding.
Furthermore it contains 7 valuable tricks to reduce the file size of your JPEGs by exploiting the technical functionality of the JPEG compression algorithm.
Ever wondered why some of your PNGs are of large file size while similar PNGs are so small?
Since this question comes up so often, I have written a follow-up to my article "Understanding JPEG" to explain the bare necessities of the PNG compression algorithm in layman's terms.
At the end you will also get 7 tips on how to get your PNGs to a REALLY small file size.
You don't like ads? Support Compress-Or-Die and become a patron who does not see ads. Your upload limit gets doubled too!
News
Image compression with AI
2023-06-25
Wow! Google researchers have now proposed a new method that combines a standard autoencoder with a diffusion process to recover and add fine details discarded by the autoencoder. Interesting to see the possibilities AI opens up when compressing images.
A year ago, generating realistic images with AI was a dream. We were impressed by seeing generated faces that resemble real ones, despite the majority of outputs having three eyes, two noses, etc. However, things changed quite rapidly with the release of diffusion models. Nowadays, it is difficult to distinguish an AI-generated image from a […]
Check out our Reddit channel if you want to comment on the news.