Hello.
I am having trouble understanding dithering. In short: I want to be able to do whatever it is Photoshop does when switching color depth (per channel) from 16-bit to 8-bit mode. The overall aim is to batch-convert normalmaps and heightmaps to an appropriate format.
To keep it simple I'm trying to convert a linear black-to-white 4k 16-bit gradient to 256 colors. I'm expecting to see no banding when zoomed in on the output. So far my only successful attempts are with ordered dithering:
magick in.tiff -ordered-dither o8x8,256 out.tiff
Which is mostly what I want, except that I'd prefer to have no discernable pattern, which I assume is what all the other dithering methods are for.
magick in.tiff out.gif
From the documentation I got the impression that default settings already should give me the result I want. This produces a gradient with undithered 16-pixel-thick bands instead.
magick in.tiff -depth 8 out.tiff
magick in.tiff -dither FloydSteinberg -depth 8 out.tiff
Same banding.
magick in.tiff -colors 255 out.tiff
magick in.tiff -dither Riemersma -colors 255 out.tiff
magick in.tiff -dither FloydSteinberg -colors 255 out.tiff
The above dithers the way I want it to, except all the way down to 64 colors.
magick in.tiff -remap out.gif out.tiff
This again dithers to 64 colors despite out.gif containing 256 colors. Tried with a 255-color palette file as well, same result. I might be misunderstanding palettes. And in general, I feel like I'm either missing something obvious or don't understand something fundamental.
(Using IM 7.0.6-3 Q16 x64 2017-07-24 / Win7)
Controlled dithering, 16-bit to 8-bit
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Controlled dithering, 16-bit to 8-bit
On "-colors", see http://www.imagemagick.org/script/comma ... php#colors :
"-depth 8" just drops precision with no dithering. (If the input has 16 bits/channel, it drops bits by dividing by 257.)
"-remap" using a map of grayscale gradient with 256 colours, and no dithering, gives an output with 256 colours, as I would expect. But dithering with "-remap" gives only 64 colours, as you say, and I don't know why.
One solution is to do your own random dithering, by adding noise, then a simple "-depth 8". Windows syntax:
g3.tiff has 256 colours, with random dithering.
The more regular the input, the more likely that a colour-reduction will give you fewer than you asked for.The actual number of colors in the image may be less than your request, but never more.
"-depth 8" just drops precision with no dithering. (If the input has 16 bits/channel, it drops bits by dividing by 257.)
"-remap" using a map of grayscale gradient with 256 colours, and no dithering, gives an output with 256 colours, as I would expect. But dithering with "-remap" gives only 64 colours, as you say, and I don't know why.
One solution is to do your own random dithering, by adding noise, then a simple "-depth 8". Windows syntax:
Code: Select all
magick ^
-size 100x4096 gradient: g.tiff
magick ^
-size 1x256 gradient: m.tiff
magick ^
g.tiff ^
-remap m.tiff ^
+write g2.tiff ^
-unique-colors info:
magick ^
g.tiff ^
+noise Uniform ^
-depth 8 ^
+write g3.tiff ^
-unique-colors info:
snibgo's IM pages: im.snibgo.com
Re: Controlled dithering, 16-bit to 8-bit
Thanks.
magick in.tiff -attenuate 0.25 +noise Uniform -depth 8 out.tiff
This was the effect I was looking for.
Although, I'd be interested to know how much of a difference a proper dithering algorithm would theoretically make on something other than a basic gradient. Am I correct in thinking that it would be trying to preserve the finer details? Or is this more or less as good as it gets for a 16-bit to 8-bit conversion?
magick in.tiff -attenuate 0.25 +noise Uniform -depth 8 out.tiff
This was the effect I was looking for.
Although, I'd be interested to know how much of a difference a proper dithering algorithm would theoretically make on something other than a basic gradient. Am I correct in thinking that it would be trying to preserve the finer details? Or is this more or less as good as it gets for a 16-bit to 8-bit conversion?
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Controlled dithering, 16-bit to 8-bit
Proper dithering distributes the error from one pixel to influence the next, so this loses less information than a random dither.
However, as a final image, I personally prefer the random dither. The high precision is lost with both methods, but patterning caused by error-distributing dither can be too distracting.
However, as a final image, I personally prefer the random dither. The high precision is lost with both methods, but patterning caused by error-distributing dither can be too distracting.
snibgo's IM pages: im.snibgo.com
Re: Controlled dithering, 16-bit to 8-bit
Okay, thanks again.
Re: Controlled dithering, 16-bit to 8-bit
Also try "-random-threshold" which is essentially a 1x1 dither (i.e., no dithering)
Re: Controlled dithering, 16-bit to 8-bit
Sorry, you'll have to expand on that. Say, "-random-threshold 0x100%" on a grayscale input gives me a monochrome dithered image. I can't see how I'd use this to get a 256-color image.
Re: Controlled dithering, 16-bit to 8-bit
Right, "random-threshold" reduces the image to black and white pixels. I think there's a way to random-dither each channel to get an 8-color image. But no way to get a 256-color image with it.