JDK-4904494 : Gray BufferedImage is too bright
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.3.1,1.4.1,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000,windows_xp
  • CPU: x86
  • Submitted: 2003-08-11
  • Updated: 2006-08-18
  • Resolved: 2006-08-18
Related Reports
Duplicate :  
Duplicate :  
Description
Name: jk109818			Date: 08/11/2003


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
Service pack 3

A DESCRIPTION OF THE PROBLEM :
Gray image incorrectly shift to bright side. Create haze
effect on the image. In my computer the reading is

image value     screen value
0                0
1                13
2                22
3                28
4                34
5                38
......................
253              254
254              255
255              255


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.compile my test code
2. move mouse cursor on the image
3. read screen value and image value

EXPECTED VERSUS ACTUAL BEHAVIOR :
Gray image incorrectly shift to bright side. Create haze
effect on the image. In my computer the reading is

image value     screen value
0                0
1                13
2                22
3                28
4                34
5                38
......................
253              254
254              255
255              255


ERROR MESSAGES/STACK TRACES THAT OCCUR :
no error message

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.event.*;
import java.awt.color.*;


public class MainFrame_1 extends JFrame {
    public MainFrame_1() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        ImageComponent1 imageComponent = new ImageComponent1(this);
        panel.add(imageComponent);
        setContentPane(panel);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new MainFrame_1();
    }
}

class ImageComponent1 extends JComponent  implements MouseMotionListener {
    BufferedImage image;
    JFrame frame;
    Robot robot;
//    RandomIter iter;
    public ImageComponent1(JFrame frame) {
        this.frame = frame;
        setPreferredSize(new Dimension(300,30));
        addMouseMotionListener(this);
        try {
            int[] bandoff = {0} ;
            int width = 256;
            int height = 10;
            SampleModel sampleModel = new ComponentSampleModel
(DataBuffer.TYPE_BYTE, width, height, 1, width, bandoff);
            WritableRaster wr = Raster.createWritableRaster(sampleModel, null);
            DataBufferByte db = (DataBufferByte)wr.getDataBuffer();
            byte[] data = db.getData();
            for ( int h = 0; h < height; h++ )
                for ( int w = 0; w < width; w++)
                    data[h*width + w] = (byte)(w & 0xff);
            int[] bits = {8};
            ColorModel colorModel = new ComponentColorModel
(ColorSpace.getInstance(ColorSpace.CS_GRAY), bits, false, false, 1,
DataBuffer.TYPE_BYTE);
            image = new BufferedImage(colorModel, wr, false, null);
            robot = new Robot();
//            iter = RandomIterFactory.create(image, null);
        }
        catch(Exception ex) {
            System.out.println(ex);
        }

    }
    public void paintComponent(Graphics g) {
        if ( image == null ) {
            return;
        }
        Graphics2D g2D = (Graphics2D)g;
        g2D.drawRenderedImage(image, new AffineTransform());
    }

    public void mouseDragged(java.awt.event.MouseEvent mouseEvent) {
    }

    public void mouseMoved(java.awt.event.MouseEvent mouseEvent) {
        Point screenLocation = getLocationOnScreen();
        Point p = mouseEvent.getPoint();
        Color c = robot.getPixelColor(screenLocation.x + p.x,
screenLocation.y+p.y);
        if ( p.x < 256 && p.y < 10 )
            frame.setTitle("x="+p.x+" y="+p.y+" screen="+c.getRed()+"
image="+p.x);
        else
            frame.setTitle("x="+p.x+" y="+p.y+" screen="+c.getRed());
    }

}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
new BufferedImage(int width, int height, int imageType)
works fine
(Incident Review ID: 179397) 
======================================================================

Comments
EVALUATION The brightness difference is caused by "gamma correction" for custom images based on GRAY color space. Usually gamma correction happens during both setting and getting processes. However, in this data buffer is filled directy, so no conversion is performed. But drawing is performed by AnyToIntargb blit (because this is custome image) that performs gamma correction. See 5051418 for detailed explanation. I am closing this bug as duplicate because this seems to be exactly same issue.
18-08-2006