Our paper was about 3.5 meters wide, and a single roll length was 2–3 kilometers which ran for 20-30 minutes. The process delivered high quality at high speed, so we printed titles like Playboy and the IKEA catalogue in every language (for a language change we only had to swap the black cylinders, since the data was optimized so the text was mostly single color black). A print run of the IKEA catalogue, around 40 million copies, took about two months. It was brain numbing but also really zen. I miss it sometimes.
Edit: found it. One picture taken from up close. Other pictures the whole image when laid out over multiple pages in the software https://imgur.com/a/OeaIWuY
I tried doing something similar a couple of years ago and gave up after running into the exact same issues in the post. It's really difficult to replicate proper halftoning on a computer screen without getting moiré patterns and weird artifacts because of PPI, aliasing, and other stuff. Beyond that, print and screens are just fundamentally different ways of rendering things.
It has some fun animation options and settings to play with, and there's other dithering algorithms to play with.
Yeah, if you're using lossless compression like PNG or GIF, adding a lossy step to reduce the number of colors in the palette can help.
If you're compressing photos, you should use JPEG or WebP.
Anecdotally, JPEG usually beats dithering, and WebP always does.
It's fine to dither images but please please admit that you're doing it for the aesthetic. WebP has very broad browser support and absolutely blows dithering out of the water for compression. You are not going to beat years of research and tuning with "use fewer colors".
I remember a YouTube video about "How we did the impossible and got full-motion video for this Sonic game on a system that couldn't do FMVs", and the answer was like, "Well, we used a low resolution, and then we reduced the color palette, and then we cut the frame rate, and then we did interlacing." None of that's impossible! That's like saying you built the Pyramid at Giza using only a bucket of Lego bricks! It's not the same pyramid! Anyone can use a lower resolution! It takes effort and teamwork to come up with a codec that actually compresses data without artifacts!
It aims to 'knock out' some areas of the image: make them transparent in the digital image so those areas are not part of the final film. This means less of the surface of the t shirt has film on it, allowing it to be breathable and flexible.
I got some DTF prints made before I knew you were meant to do this. The tutorials online required a lot of steps so I made the above for next time. Not tested for real yet.
You can go down a rabbit hole of dithering algorithms too, like Floyd Steinberg[1]
[0] https://github.com/makew0rld/didder [1] https://en.wikipedia.org/wiki/Floyd%E2%80%93Steinberg_dither...
They did in the article.
> My goal was to immitate a printed image.
Depending on the image context it can also backfire, though not so much for photos, but rather screenshots. E.g. sometimes a 2 color dithered image results in a much bigger PNG than, say 16 colors without dithering, because bigger areas of uniform color compress much more efficiently. So I usually just try "everything", to find some sweet spot between file size and quality.
Is there a tool that allows you to select which area of the image to use what dithering parameters and color count for, with a live preview? I know I'll vibecode one myself just to see what it looks like, but maybe this already exists in a "real" application? Then you could e.g. use dithering on the faces, but for the background just a few colors without dithering.
A dithered image almost certainly beats a non-dithered JPEG compressed image in terms of file size, because you can JPEG compress the dithered image. Thus, if you like the look of a dithered image, you get file size reduction as a bonus.
I swear, some people on HN intentionally misinterpret and misrepresent the text of an article just to argue against it in bad faith with these smarmy "um actually" type arguments. For some reason I do not understand, Hacker News tends to surface these comments near the top of its comment sections.
> This image features a close-up abstract scene styled with a classic halftone (Ben-Day dot) pop-art filter ...
https://share.gemini.google/O5eqZOKxwzw3
> This image is a halftone/thermal print styled photograph. The photo features a group of four people posing closely together indoors or in front of a windowed backdrop:
Surface-stable fractal dithering:
https://www.youtube.com/watch?v=EzjWBmhO_1E
And the technical deep dive:
Unhalftoning is called descreening.
I use this:
Very important clarification, there.
>But if you care about the method this is not dithering.
> I looked it up, the translation in this case is, in fact, simply "half tones" :^)
I would not have clicked on “How My Images Are Dithered” but this truncated version made it sound more like an interesting bug story.
That's backwards. Dithering (and simulated halftoning, as in this case) adds detail/noise, making images harder to compress efficiently.
To learn more about halftones, I'd recommend PDF specification, pages 303-307.
https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/p...
For an algorithm like JPEG, if anything, you'd need to blur rather than dithering.
Like ~99% of images you encounter on the Web.
Yes. Photoshop does the correct thing when going 8bit via the "Mode" menu. On the other hand, if you do "Export As → PNG" and check the "Smaller file (8-bit)" checkbox, it does NOT dither, and it produces banding artifacts.
> Consider that a grayscale gradient can only have 256 distinct levels.
This is true, but also keep in mind that for print and low dynamic range displays we humans only need approximately 256 levels, as long as the levels are perceptually spaced out evenly. 8 gamma corrected bits per channel actually made sense for a long time, for both print and for TVs & monitors, until HDR displays came along, relatively recently. Needing dithering for 8 bit images displayed on a 10 bit display is perhaps less surprising than needing dithering even when your display and your printer are both only 8 bits, right?
I don't know much about dithering. But when I visit other people's sites and they dither their images in cool ways I always wonder how they do it. So in case anyone is wondering, here's my current method for dithering these pink images.
Edit: Almost like I know myself too well — the pictures now look like this instead: 
Which is covered in the post.
Welcome to all the hacker news readers who clicked on this post. I am thankful and glad that this post has come to entertain some of you. Here are some things I feel the need to add to the post since it has left my regular audience:
There seems to be discussion about whether this counts as dithering. As evidenced by the very first sentence of the post, I am not an authority on the subject. But here is what Wikipedia seems to think:
Dithering is analogous to the halftone technique used in printing. For this reason, the term dithering is sometimes used interchangeably with the term halftoning particularly in association with digital printing. (link)
In any case — I am/was only aware of this technique being used for AM grid printing, as briefly layed out in the post. So I thought it might be fun to play pretend a little.
this is a very inefficient method of reducing the size of an image file — I'd even say this little experiment has nothing at all to do with decreasing file size (in some unlucky cases it will even increase the size of your image). I mention this a few times in the post. It's just a bit of playing around with a certain aesthetic
please don't feed images of me and my friends to an LLM?? The code for achieving each effect is all over this page. Just make your own image and feed that to an LLM.
Dithering, beside making a picture look (to put it professionally) cool as fuck, can also reduce file size (by using less colors while maintaining details) and thus needed storage (if using only the reduced images) and the weight of your website for the client. That's why sites like Low Tech Magazine use it, for example.
The idea of pink images came from a post a while back, when I tried this before. The post Designing without color introduces the idea of the current design, where I try to get a sort of black and white "printed" vibe, using color only for emphasis. (This makes sense only when you are a light mode user like me).
The image back then, with the old method, looked like this: 
The key difference here being that I limited the picture's palette to true monochrome: black and this pink. Also, the weird "dithered" dots are much bigger.
My goal was to immitate a printed image. While individual pixels on a screen may have the luxury of setting variable values of red, green and blue — making the grid of repeating RGB lights on your screen light up with different intensity — things work a little differently on paper (and other print substrates).
Getting the limited palette of colors your printer is working with to give the illusion of more colors requires using a grid/matrix of dots. You can go about this in three different ways: AM, FM and hybrid grids. The amplitude here being the size of the dot and the frequency, well … the frequency. Making a dark spot with AM grids means big dots, in FM grids it's lotsa dots.

The top shows an FM print: the dots look chaotic.
The bottom shows AM: all dots show up in a predictable pattern and light spots have smaller dots
The problem with amplitude modulated dots is that if you approach this naively you will end up getting unwanted patterns in your images: a so-called Moiré.
![]()
For this reason, there is a rule (DIN 16547) about how exactly the colors are to be offset in an AM print to try and avoid them getting in each others way. Since FM grids are random they do not suffer from this problem.

I access my server via the command line — so I use a command line tool to quickly edit images. The tool is called imagemagick and is called using the "convert" command.
I found the method to create this illusion online (can't find the link) and adapted it a little. So I can't claim to be the expert on what each individual argument does, but I will try to explain it.
convert "oldfile" -resize 800 -set option:distort:viewport '%wx%h+0+0' \
-colorspace CMYK -separate null: \
\( -size 2x2 xc: \( +clone -negate \) \
+append \( +clone -negate \) -append \) \
-virtual-pixel tile -filter gaussian \
\( +clone -distort SRT 2,0 \) +swap \
\( +clone -distort SRT 2,15 \) +swap \
\( +clone -distort SRT 2,45 \) +swap \
\( +clone -distort SRT 2,75 \) +swap +delete \
-compose Overlay -layers composite -set colorspace CMYK -combine \
"newfile"
Here's what it does generally: resizes the image to 800px in width (who needs more?), sets the color to CMYK, applies a background to fill the empty space left by rotating (and sets a gaussian blur to filter noise), splits up into the colors, scales them up a bit (for bigger dots) and distorts them (in this case: rotates them) and at the end it combines the 4 images into one again.
The image we generate by running this on the original file looks like this:

Before combining them, these are the individual colors dot grids:

This sets C at 0°, M at 15° etc. But whatever. Zooming in and out doesn't make any weird artifacts apparent so it's good enough.
If we increase the size of the dots to a ridiculous degree (8x8), you can get a better look at what is happening.

After sleeping on it and reading the post back, the solution for a pic limited to truly CMYK colors in an AM grid is apparent. For reasons I get into later this is NOT a good way of reducing file size (apart from the fact that limiting colors and resizing the image to 800 in width always reduces the size, everything else is pretty much stacked against that goal). It does, however, look cool.
With the above method, the dots do not vary in size. Why should they? As we already discussed, a digital image (unless I have a GIF or PNG-8 situation somewhere) can give varying intensity of light for R, G and B per pixel. So when we look at the big image above we can cleary see some of the squares are just darker than others. For a true immitation this will not do!
All we need to do is to limit each channel's colors to 2 before combining them again. This is very obvious in hindsight. Idk why the person I got the original command from didn't do this.
convert "oldfile" -resize 800 -set option:distort:viewport '%wx%h+0+0' \
-colorspace CMYK -separate null: \
\( -size 2x2 xc: \( +clone -negate \) \
+append \( +clone -negate \) -append \) \
-virtual-pixel tile -filter gaussian \
\( +clone -distort SRT 2,0 \) +swap \
\( +clone -distort SRT 2,15 \) +swap \
\( +clone -distort SRT 2,45 \) +swap \
\( +clone -distort SRT 2,75 \) +swap +delete \
-compose Overlay -layers composite -colors 2 -set colorspace CMYK -combine \
"newfile"
This will produce an image that looks like this:


In retrospect I wonder if I might try out images like this instead of pink. If all I want is the general vibe of the grid then pink is fine. Though it does have more colors (shades of pink) for less colors (actually useful distinct ones). Who said blogging about your stupid idea isn't useful?
The script for the old way of doing it had the values of -distort SRT set to "2 (rotation)", meaning it scaled the colors up to 2, making bigger dots.
After running the script above, the colorspace was once again converted, to Gray this time, after which the colors were leveled to monochrome: black and this pink. The whole command for those who want to try:
convert "oldfile" -resize 800 -set option:distort:viewport '%wx%h+0+0' \
-colorspace CMYK -separate null: \
\( -size 2x2 xc: \( +clone -negate \) \
+append \( +clone -negate \) -append \) \
-virtual-pixel tile -filter gaussian \
\( +clone -distort SRT 2,0 \) +swap \
\( +clone -distort SRT 2,15 \) +swap \
\( +clone -distort SRT 2,45 \) +swap \
\( +clone -distort SRT 2,75 \) +swap +delete \
-compose Overlay -layers composite -set colorspace CMYK -combine \
-colorspace Gray -colors 2 +level-colors black,#A2719B \
"newfile"
If we zoom in on the image before and after leveling the colors, we can see the dots do seem more like they vary in size. I omitted the -resize flag to give you a better view of the details.

While not entirely accurate, I think this method gets the most printy feel out of an image. Sadly it can swallow a lot of detail, even if the dots aren't scaled up. So I abandoned this after a while (also I got sick of looking at it).
Edit: now compare to the real deal:


Monochrome is a cool idea but just has limited use for the blog (and other pics on the website). I need some more depth. What I need is more values of pink. I get these by utilizing the -remap flag.

convert "oldfile" -resize 800 -set option:distort:viewport '%wx%h+0+0' \
-colorspace CMYK -separate null: \
\( -size 2x2 xc: \( +clone -negate \) \
+append \( +clone -negate \) -append \) \
-virtual-pixel tile -filter gaussian \
\( +clone -distort SRT 1,0 \) +swap \
\( +clone -distort SRT 1,15 \) +swap \
\( +clone -distort SRT 1,45 \) +swap \
\( +clone -distort SRT 1,75 \) +swap +delete \
-compose Overlay -layers composite -set colorspace CMYK -combine \
-remap "$palette" -colors 32 "newfile"
For images like the one I've been using everything works beautifully. But with images that are very overwhelmingly light, there can be issues.
Here's an example:
Original image
After running script
After manual edit
The edit in question: increasing brightness to 300%, Saturation to 200%, inverting colors and remaping them to pink
convert "oldfile" -modulate 300,200,100 -negate -remap $palette "newfile"
This is possibly because my color palette is kinda bad.
If all you care about is the result then you could say the image has been dithered, especially in the old method. Using only two colors we created the illusion of semitones (is this appropriate usage in English?)*. The same is basically true for the new method as well.
But if you care about the method this is not dithering. Or at least it's the most unnecessarily computationally expensive form of dithering I've come across. Let's walk through the steps one more time:
This whole thing, on my laptop with an 11 year old CPU, can take 10 seconds if the image is big. The file size is not exactly "small" (though still smaller than unscaled pics with more than 32 colors). I can imagine the pattern isn't doing compression algorithms a huge favour. If you value your time or care about actually reducing an image's size do not do this.
#!/bin/bash
temp="/tmp/images"
palette="/path/to/palette.png"
rm $temp
if [[ $1 = "" ]]; then
if [ -d smol ]; then
echo must run with argument
else
mkdir smol big
ls -r *.webp > $temp
ls -r *.png >> $temp
ls -r *.jpg >> $temp
ls -r *.jpeg >> $temp
ls -r *.gif >> $temp
fi
else
ls -r *$1 > $temp
cp *$1 big
cat $temp
cp $(cat $temp) big/.
fi
i=$(cat "$temp" | wc -l)
echo $i
while [[ $i -gt 0 ]]
do
name="$(head -n $i $temp | tail -n +$i)"
echo "doing $name"
convert "$name" -set option:distort:viewport '%wx%h+0+0' \
-colorspace CMYK -separate null: \
\( -size 2x2 xc: \( +clone -negate \) \
+append \( +clone -negate \) -append \) \
-virtual-pixel tile -filter gaussian \
\( +clone -distort SRT 2,0 \) +swap \
\( +clone -distort SRT 2,15 \) +swap \
\( +clone -distort SRT 2,45 \) +swap \
\( +clone -distort SRT 2,75 \) +swap +delete \
-compose Overlay -layers composite -colors 2 \
-set colorspace CMYK -combine \
-colors 64 "smol/$name"
(( i-- ))
echo $i
done
To end with, here is the original image with actual dithering (FloydSteinberg)

This file is smaller than the new (pink) method (but bigger than the old one).
Edit: the true method will produce a smaller file for this image :^} (though this is not a rule!)
You can ofc do the same thing with RGB instead of CMYK. That wouldn't really be as accurate for a "print vibe"!! but here's the RGB AM grid version:

📍 Posted from Erfurt, DE
HDR is what changed - it requires more than 8 bits per pixel, by definition!
Again, if you only have LDR (low dynamic range), the human visual system’s “just noticeable difference” or JND in the perception literature demonstrates we only need 8 bits when looking at things under ‘indoor’ lighting conditions. You don’t need dithering if you use LDR on a single specific 8-bit display. You do need dithering when either moving to a different display than the one you started with, or using an HDR display - capable of displaying more than 8 bits of color resolution.