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.
Through exchanges with illustrator and senior concept artist David Blatt (@KOPF_STOFF), it has emerged that it is possible to obtain the original JPEG. The article has been expanded accordingly.
I'm quite active on Twitter, and every now and then I come across tweets where users are upset about the lousy quality of their posted images after Twitter compresses them and doesn't speak well of Twitter.
But is the quality really that bad? Does Twitter really not care about image quality? Is Twitter trying to save storage space on its servers at all costs? Or are the users themselves to blame and have already uploaded their images in poor quality?
I took a closer look at what Twitter actually does with your images in the tweets. I analyzed the created image files with COD's own analysis tool compress-or-die.com/analyze.
In fact, there is no official entry from Twitter about how exactly the images are actually processed. I found this forum entry from ex-Twitter employee Nolan O'Brien from December 2018, updated to January 2020. Since this article is already a few years old, I will check the statements placed there and of course test some things beyond that that may have been (intentionally?) not mentioned there.
In order to be able to test how the images uploaded in tweets are compressed, I first had to know which image sizes are actually created by Twitter. In order not to generate unnecessary traffic, Twitter only delivers the images in the respective pixel size that is sufficient for the client (i.e. your PC or smartphone) at the moment of viewing. So that you don't have to wait unnecessarily while surfing, various pixel sizes of the images are generated directly after the tweet is created. For security reasons, you will never be able to retrieve your original image from Twitter.
By looking into the Twitter API documentation you learn that there are certain fixed sizes for images.
These are named thumb, small, medium and large.
With these names you can now compose the valid image URLs in the way Twitter does in its interface:
However, when checking my Twitter timeline in the desktop client, I noticed that Twitter not only uses these names, but also other names such as 240x240, which are not even mentioned in the API documentation.
But since the value 239x239 for the parameter name again does not work, I have determined the valid names by a script. This ultimately resulted in the following names for images whose quality is to be tested:
So Twitter creates nine different pixel sizes from your source image. All sizes except thumb are scaled down to fit the outer dimensions while maintaining the aspect ratio. Only thumb is cropped to a square size toward the center.
Scaling up is never done. If you upload a 1000×1000px image, this size will also be delivered for medium and large. Strictly speaking, there can be ten possible sizes.
You probably noticed in the image URLs above that you can also use the file format png or jpg for the format parameter. That's true, and it does indeed generate the appropriate file format, but ultimately we are dependent on which image format Twitter decides to use when generating the URLs in its interface. Nevertheless, I tested all the possibilities of images that Twitter can generate: So all 18 variants.
Fun fact: The Twitter compression pipeline can also generate webp images, but I've never seen this being used in the Twitter interface. Whether the feature exists only for testing reasons (perhaps in response to this request) or whether Twitter has more planned for it, I unfortunately could not find out.
I performed the test with a small set of my own JPG, PNG, GIF and WebP images supplemented by numerous meta data. Of course I followed the upload restrictions mentioned on this Twitter Help Page, which say that an image can only be up to 5 MB in size and must be a GIF, JPG, or PNG... which is not completely correct, as uploading a WebP also works, which is also confirmed on this API Docs Page.
JPG image taken by me with my smartphone with meta data like GPS location data, embedded thumbnail and color profile, EXIF and IPTC data etc.
A smaller version of the first image, which has been rotated, but with correct EXIF meta-data added for 'orientation'. Browsers usually rotate the image correctly, so the preview should look correct.
A 4092px wide version of the first image with a quality of 92, which should be preserved when tweeting if possible.
A smaller version of the first image in WebP format.
A smaller version of the first image in PNG format (1000×748px).
A smaller version of the first image in PNG format (680×509px).
CMYK JPG with embedded color profile 'U.S. Web Coated (SWOP) v2'. Quelle: https://en.wikipedia.org/wiki/File:Channel_digital_image_RGB_color.jpg
A PNG with a gamma value of 100, which can indicate the success of a gamma correction.
A JPG with a color channel swapping ICC profile.
A PNG with a color channel swapping ICC profile.
In addition, a few other test images were used to partially test special peculiarities.
An 8- or 24-bit PNG is output (depending on the input format; will be described in more detail later).
All meta data like Exif, IPTC or similar except for the gAMA chunk (contains the gamma correction value) will be removed. A possibly embedded color profile will be applied if the output format matches the input format.
The quality of the JPG files is not as good as the numbers of the quantization tables (according to the standard tables quality 85 for luminance and chrominance) suggest. Comparing the Twitter result with that of a JPG created with cjpeg from the libjpeg-turbo package, it is easy to see how comparatively poor the quality of Twitter compression is.
Pay close attention to the sharpness of the logo and the B on the blue background. The artifacts around the G on the green background are also slightly more pronounced.
The JPG created by Twitter.
The JPG created with cjpeg.
Presumably the image was repeatedly converted to JPG format over and over again, which is unfortunately extremely detrimental to the quality of a JPG because each time it is saved, the artifacts of the previous save are amplified.
The JPG algorithm, of course, knows nothing about artifacts and assumes that the artifacts created by the previous conversion belong to the image. It therefore tries to compress them for later display as well, which ultimately leads to new artifacts.
This multiple compression is definitely the biggest weakness of the Twitter compression pipeline and should never occur this way.
For accurate image reproduction in print, professional creatives often use ICC color profiles. Therefore, I once uploaded a color profile test image which shows the colors in the correct order only when the embedded color profile is processed correctly, namely (R)ed, (G)reen and (B)lue.
The color profile is only transferred to the output format that was also used as the input format.
In the case of JPGs, this is not a problem because Twitter is guaranteed to generate a JPG from a JPG. In the case of the PNG, it can become a problem if your PNG no longer fits in 900×900px and is thus subjected to Twitter's internal format test, which can decide to output it as a JPG. However, we will come to the topic of when Twitter decides which image format in detail later.
When converting a CMYK JPG, Twitter cannot of course adopt the color profile into the output format, because the image is basically converted into the RGB color space. However, the CMYK color profile is unfortunately completely ignored during the conversion, which leads to a rather pale end result.
The embedded color profile 'U.S. Web Coated (SWOP) v2' is ignored by Twitter.
This is how it should look after correct conversion.
To check the correct processing of a gamma correction, I use a self-created image with an exaggeratedly high gamma value of 100 (normal is 2.2).
This shows "OK" if the image is displayed correctly, or "Broken" if the gamma correction was not done correctly.
By the way, for such a test I advise against using the checkerboard images that are widely used for gamma tests.
These are images that effectively superimpose two images, such as the relatively well-known apple-pear image:
These work by displaying the image contents of the two mixed images only at every second pixel.
If you scale such images, the mixing of the pixels produces unwanted results and could be mistaken for a gamma correction error.
As you can clearly see, the PNGs are rendered correctly.
If the source image contains a gAMA chunk(this contains the gamma information in PNG format), Twitter will correctly include this chunk in the output PNG.
The JPG files are displayed incorrectly after conversion by Twitter.
Since gamma EXIF data is normally interpreted by very few programs, the correct procedure would have been to convert the image data to a gamma value of 2.2 according to the input gamma values and not to include gamma meta data in the image.
As in the case of the problematic color profile processing, this also means that it can become a problem here if your PNG no longer fits in 900×900px and is thus subjected to Twitter's internal format test, which can decide to output it as a JPG.
If the input image is a GIF with only one frame, the image is still converted to a 24-bit instead of an 8-bit PNG.
This does not result in a visible loss of quality, but Twitter could save storage space here, since the GIF format only supports 256 colors according to the specification anyway, so the 8-bit color depth would have been sufficient in any case.
However, since probably negligibly few Twitter users will upload 1-frame GIFs, this approach is absolutely justifiable.
Now that we know how Twitter's compression pipeline works, the next interesting thing is which image Twitter uses and where.
The output dimensions of the output image are relatively easy to determine. Twitter respects the Device Pixel Ratio and therefore, for example, with a requested width of 415px and a DPR of 2, delivers the image in 900px width and not in 680px.
What is much more interesting now is which image format Twitter actually uses, since the PNG format makes more sense for icons, graphics and images with a lot of areas of the same color and few colors, while the JPG format is the more suitable format for photographs.
According to the 2020 forum post already mentioned above, Twitter works like this:
Depending on whether the internally generated JPG version or the PNG version is smaller, the corresponding format is used. At which pixel dimensions the two competing images are compared is unfortunately not mentioned.
By the way, on a mobile device such as a smartphone, the same images are played out as in the browser, although here, of course, the previously mentioned device pixel ratio plays a greater role. The upload of multiple images in one tweet is also irrelevant. Each image is subject to the rules mentioned here.
Additionally, according to the forum entry, there is the possibility to get the original view of a JPG.
When uploading a JPG, four points must be observed, which I have added another point to a 5-point rule:
The image must fit into the outer dimensions of 4096×4096px.
The file size of the image must be smaller than 5MB.
The image must not be rotated by an EXIF meta-orientation.
The compression rate must reach at least 1 pixel per byte.
The point I added: The image must be in an RGB color space.
If these five points are observed, the JPG is not recompressed. So you get the view of the original image.
The fourth point is quite in need of explanation.
But it simply says that the file size in bytes must be smaller than the product of height and width.
Let's take this picture for example:
JPG with dimensions 4092×3062px and file size of 2.48 MB (2,484,348 Bytes).
Multiplying height and width (i.e. 4092×3062) gives the value 12,529,704.
If the file size in bytes remains below this value, as in this example (2,484,348), it is possible to preserve the original view of the original image.
In this example, the goal was easily achieved, but for JPGs with smaller dimensions and JPG quality values greater than 95, it can quickly happen that this rule is no longer respected.
It is also interesting to note that this image is displayed exclusively in the detailed view (i.e. after clicking on the image in the tweet). If one has only 1200px available in the browser in width, for example, an uploaded 4000px wide image would still be used for display.
If the rule is not met, the next larger version of the highly compressed image would be selected instead, i.e. large (2048×2048px).
In fact, the statements made in the forum entry are still consistent with how the Twitter compression pipeline works today.
As to what I found out beyond that, I can say that the working methods used by Twitter and compression values applied are mostly fine and understandable, so reasonable results can be achieved in tweets if the rules for the source image are followed.
However, if one violates these rules, the image quality becomes quite lousy due to the multiple compression mentioned above.
That's also the crux of the matter:
Because Twitter hardly provides any official information on how to upload your images and how they are then compressed and played out, many users are left alone, which then ultimately results in frustration with Twitter due to ignorance and the resulting upload errors.
In my opinion, a simple forum entry from a former employee is simply not enough for professional communication.
I would like to give you the following tips for your pictures:
If you have photographic material that should be displayed in the detail view in the best possible way, pay attention to the 5-point rule mentioned above. In this case, however, the preview image will be blurred in any case.
Images that only serve to support the visualization of the tweet and whose detail view is unimportant, I recommend uploading as sRGB PNG in max. 900×900px, because in this case the image is never converted to JPG and thus remains razor sharp (since uncompressed).
If you use an 8-bit PNG as the source image, the size in pixels is also unimportant.
When uploading a PNG with photographic content, make sure you have converted the gamma value to 2.2 beforehand and do not use color profiles.
CMYK image material should not be uploaded directly, but converted to sRGB fab space beforehand.
Pro-tip on our own behalf: compress-or-die.com of course works with a functioning gamma correction, a clean color profile conversion to sRGB and the consideration of CYMK profiles. It is a good idea to have the images planned for the tweets prepared once in Compress-Or-Die.
If you get images that differ from these results, something may have changed in the Twitter compression pipeline. If so, I would appreciate a few lines so that I can revise the article. But also otherwise I am happy about criticism, feedback and praise of any kind.
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.