GNOME Bugzilla – Bug 97777
use error-diffusion for gradients to reduce banding
Last modified: 2003-07-21 01:14:28 UTC
Gradients have banding problems: here using colors: #5f8096 and #000000 http://scizzo.helloween.kicks-ass.org/bug-gradient-1.png here with: #8b818e and #000000 http://scizzo.helloween.kicks-ass.org/bug-gradient-2.png
Could you explain what the problem is? I do not see any obvious banding problems. Of course, the images are very wide and it is not possible to have more than 256 intensity levels per channel (R, G, B) so there are some groups of pixels that have the same color, but I would not call that a banding problem so I suppose that you are refering to something else. Please explain...
Did you enable "Adaptive Supersampling" in the Blend tool to create these gradients? I don't think you did but you probably should have since that's what this option is good for. Should IMHO be closed as NOTABUG.
OK, let's summarize it as this: There's no bug in the current implementation but gradient rendering could be improved by spreading the error across some pixels. This would create sort of a dithering effect. Basically the technique used in printer drivers but with more colors and smaller errors ;-)
I am setting the target milestone to "Future", which will probably be around GIMP-2.0. The reason for this is that it will be much easier to implement this feature if the gradients can be rendered internally with 16 bits per channel and then dithered to 8 bits per channel. Since GIMP-2.0 will support painting operations done with more than 8 bits per channel, I think that it would be more appropriate to implement this improvement at that time. It would also be possible to implement this earlier, but this would be limited to one tool and the time spent implementing this feature would probably be better spent implementing the things that will move us closer to the 2.0 release.
If you use spread filter as poor man dithering, you get a nicer look to the eye. Looking at the code it seems adaptive does subpixel rendering when what really matters is to shake around the colours to fake more colours than the avaliables. Make more samples per pixel will not help if the problem is a constant value area you want to make variable.
A better fix would be to change the gradient API to return a double that can be queried at an arbitrary point along the interval of the gradient. The user of the gradient can then query at the relevant points and dither accordingly. Moving the gradient code to 16 bits would not solve the problem for 16 bit users.
The gradient API already uses double (from app/core/gimpgradient.h): struct _GimpGradientSegment { gdouble left, middle, right; GimpRGB left_color; GimpRGB right_color; GimpGradientSegmentType type; GimpGradientSegmentColor color; GimpGradientSegment *prev; GimpGradientSegment *next; }; void gimp_gradient_get_color_at (GimpGradient *gradient, gdouble pos, GimpRGB *color); GimpGradientSegment * gimp_gradient_get_segment_at (GimpGradient *grad, gdouble pos); Remember that GimpRGB also stores the color channels as doubles.
Good! I misunderstood your comment above. This means that the gradient tool should have an optional dithering mode.
Created attachment 18442 [details] [review] Patch against 1.3.16 adding the dither capability
There are a few issues with the patch but basically it looks good and should be applied after fixing these: (1) It should use the more portable GRand functions from GLib instead of rand(). (2) It should follow the GIMP coding style as defined in HACKING. (3) The patch changes generated source code instead of changing the file in tools/pdbgen/pdb.
Created attachment 18471 [details] [review] Cleaned up version of the dither patch
2003-07-21 Sven Neumann <sven@gimp.org> * app/core/gimpdrawable-blend.[ch] * app/tools/gimpblendoptions.[ch] * app/tools/gimpblendtool.c * tools/pdbgen/pdb/misc_tools.pdb * plug-ins/script-fu/scripts/: applied a slightly modified patch from Alastair M. Robinson that adds dithering to the blend tool (bug #97777). * app/pdb/misc_tools_cmds.c * libgimp/gimpmisctools_pdb.[ch]: regenerated.