ImageMagick's -posterize 2
flag can be used to convert an image to 1 bits (2 levels) per R/G/B channel. But is there a way to convert to a format where I have two sets of 8 colors, with half and with full intensity? In other words, my target format is 4 bits per pixel: 1 bits per R/G/B and 1 fourth bit for luminosity.
EDIT for clarity based on some comments:
With -posterize 2
, you get 8 colors total, since you have three channels and two levels per channel (since 2³ = 8):
Now imagine I have access to seven more colors (because "half-bright black" is still just black):
So I'd like to quantize (?) my picture to these total of 15 colors.
As for the output format, it shouldn't matter, the same way you can use -posterize 2
to e.g. produce a PNG that is formally 24-bit RGB, it just doesn't contain any non-0 or 255 values in any channel.
Based on @Mark Setchell's comment, using these two answers I was able to do this with a two-step process:
Generate an image containing the palette
$ convert $(for l in 128 255
do
for r in 0 $l
do
for g in 0 $l
do
for b in 0 $l
do
echo "xc:rgb($r,$g,$b)"
done
done
done
done) +append palette.png
This generates a file with 16 colors, because xc:rgb(0,0,0)
is generated twice; but that should be OK AFAICT.
Use this palette for color mapping
$ convert foo.png +dither -map palette.png result.png
While this does technically do what I set out to do, it turns out its result is quite poor; but that's for a separate question.