I am not very good with Java2D, but the color problem described is mostly due to incorrect LCD representation of sRGB color space on the device. Nevertheless, manual visual smoothing of this could probably also be done by changing the individual colors independently on each row. If there is a visible color shift, then it is again related to incorrect representations.

A color trained human with perfect vision, under perfect conditions is capable of distinguishing somewhere in the region of 5-8 million colors, when the observations are made following the CIE guidelines for reflected colors, 10 degree observer with a D65 light source. However, the sRGB color space only covers a small subset of the total perceivable color space, something like less than a quarter. LCD displays have been notorios for being extremely bad in representing that limited color space as well.

Cheers
Niclas

On 6/25/06, Jim Graham <[EMAIL PROTECTED]> wrote:
Here's a guess - you basically want the LSbit of the raster to have a
regular pattern to it rather than be banded.  If you don't want to
reinvent the GradientPaint wheel, then you could write a delegating
Paint implementation that used GradientPaint to generate an initial
Raster and then filter its result into a new Raster to return as the
"answer".  This would defeat the OpenGL accelerated GradientPaint code
if you are using that pipeline, but it may minimize the effect of the
banding.  Now where you are getting a sudden shift from one gray level
to another you would then be getting a subtle change in the LSbit dither
pattern which may be less detectable by human eyes.

        int gpbuf[];
        int mybuf[];
        for (int y = 0; y < h; y++) {
            int bits = y & 1;
            bits = bits << 8;
            bits = bits << 16;
            // bits is 0x01010101 for odd rows and 0x0 for even
            for (int x = 0; x < w; x++) {
                mybuf[myoffset+x] = gpbuf[gpoffset+x] ^ bits;
                bits ^= 0x01010101;
            }
            myoffset += myscan;
            gpoffset += gpscan;
        }

                        ...jim

Ben Galbraith wrote:
> Jim,
>
> Thanks for looking into this, and thanks to swpalmer for creating the
> test case.
>
> I realize why the bars appear, and sadly, they appear on the LCDs
> I've tested as well. Rather than try and get you guys to introduce
> new features into your rendering engine (dithering in a 24-bit
> environment, for example) I was hoping some graphics gurus could
> tutor me on how to create grayscale gradients of limited range that
> don't have banding problems.
>
> It sounds like from your last paragraph that I should try a different
> set of colors above 50% luminance?
>
> Ben
>
> On Jun 20, 2006, at 11:48 PM, Jim Graham wrote:
>
>> When I run this case I can just make out 29 extremely faint bars on
>> the
>> screen which is exactly how many possible colors there are between the
>> endpoints you chose so it looks like I am seeing adjacent colors on a
>> true-color display.  I'm a bit surprised that my eyes are that
>> sensitive
>> and that my LCD panels are that accurate (these are decent, but not
>> top-of-the-line, monitors and often consumer LCD monitors don't really
>> provide the full 256 shades of each color component so I guess I
>> lucked
>> out there).
>>
>> If you see it worse on other monitors (in particular, fewer than 29
>> bars
>> across the window) then it may be that those aren't true 24-bit
>> panels/displays.
>>
>> We currently only worry about dithering on 8-bit indexed destinations.
>> We have a request outstanding for dithering on 15/16-bit displays, but
>> we haven't gotten to it.  This would be the first request for
>> dithering
>> on a TrueColor display.  ;-)
>>
>> I agree that the problem is visible, but it is a lot less visible with
>> colors and with other parts of the grayscale spectrum (you chose a
>> band
>> of 30 colors just below 50% luminance where it is most
>> noticeable).  It
>> would be a fairly low priority for us to fix right now.  Perhaps
>> when we
>> add support for >8bit per component image formats we might address
>> issues like this.  You might want to file a feature request on this so
>> it doesn't get lost...
>>
>>                        ...jim
>>
>> [EMAIL PROTECTED] wrote:
>>> I was bored, so here's a test case... I can see the banding, just
>>> barely.  I suppose some monitors will make it look worse than
>>> others.  In any case I think the solution is dithering, but you
>>> will have to do it manually, simply supplying the rendering hint
>>> (g2.setRenderingHint
>>> (RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE); )
>>> doesn't seem to have an effect on the behavior of GradientPaint.
>>>
>>> [code]
>>> /*
>>>  * Gradient.java
>>>  *
>>>  * Created on June 5, 2006, 10:29 PM
>>>  *
>>>  */
>>>
>>> package scott.palmer;
>>>
>>> import java.awt.Color;
>>> import java.awt.GradientPaint;
>>> import java.awt.Graphics;
>>> import java.awt.Graphics2D;
>>> import javax.swing.JFrame;
>>> import javax.swing.JPanel;
>>>
>>> /**
>>>  *
>>>  * @author Scott Palmer
>>>  */
>>> public class Gradient extends JPanel
>>> {
>>>         public static void main(String [] args)
>>>         {
>>>                 JFrame f = new JFrame("Gradient with Banding
>>> issues");
>>>                 f.setContentPane(new Gradient());
>>>                 f.setSize(800,200);
>>>                 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>>>                 f.setVisible(true);
>>>         }
>>>
>>>         protected void paintComponent(Graphics g)
>>>         {
>>>                 Graphics2D g2 = (Graphics2D) g;
>>>                 g2.setPaint(new GradientPaint(
>>>                                 0,0,new Color(101,101,101),
>>>                                 getWidth(),0,new Color
>>> (130,130,130)));
>>>                 g2.fillRect(0,0,getWidth(),getHeight());
>>>         }
>>> }
>>> [/code]
>>> [Message sent by forum member 'swpalmer' (swpalmer)]
>>>
>>> http://forums.java.net/jive/thread.jspa?messageID=119469
>>>
>>> =====================================================================
>>> ======
>>> To unsubscribe, send email to [EMAIL PROTECTED] and include in
>>> the body
>>> of the message "signoff JAVA2D-INTEREST".  For general help, send
>>> email to
>>> [EMAIL PROTECTED] and include in the body of the message "help".
>>
>> ======================================================================
>> =====
>> To unsubscribe, send email to [EMAIL PROTECTED] and include in
>> the body
>> of the message "signoff JAVA2D-INTEREST".  For general help, send
>> email to
>> [EMAIL PROTECTED] and include in the body of the message "help".
>>
>
> ===========================================================================
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
> of the message "signoff JAVA2D-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

=========================================================================== To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to