Skip to main content

Color difference between BufferedImage and hardware-rendered graphics

4 replies [Last post]
mkae
Offline
Joined: 2010-04-19
Points: 0

Good evening all,

I'm new at posting here (though not at reading :p)... I am currently facing an issue, that may have to do with hardware acceleration under Windows/Java 1.6 (u19) VS. non-accelerated BufferedImages. I googled for this issue, searched these forums, and read further about VolatileImages as well... hopefully you can point me in the right direction or give suggestions. Here is some context :

In order to draw components with rounded corners (cropped), I am splitting the paint job into 3 areas, the center area being painted directly to the current graphic context, the left and right areas being painted to BufferedImages, so that I can use an AlphaComposite to create the rounded corners "mask". See issue 1 in the following screenshot http://sl8er.free.fr/java/bufferedimage-volatileimage.png .

As you can see, I have a color difference between areas using accelerated rendering (outlined in green), and areas using BufferedImages (outlined in orange).

If my diagnosis is right, one trick could be to use VolatileImages instead, so indeed in that case, the color difference goes away, but I have now problems with drawing VolatileImage to another VolatileImage's graphic context (see issue 2 in the screenshot). Compositing of my rounded corners "mask" is broken over the intersection of the two areas using VolatileImage. Question: is this considered as a contentsLoss or is it something else?

I would be very grateful if somebody could point me to the right direction to fix one of these two issues.

Cheers,

Mika

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mkae
Offline
Joined: 2010-04-19
Points: 0

Ok, my mistake for the second issue, it was due to some clipping optimization that - strangely though - works with BufferedImage and not with VolatileImage... Does one of these two automatically set the clip on its graphic context?

Anyway, has someone ever heard about color difference between hardware-rendered graphics and graphics rendered to BufferedImage... Here's a hint, it only happens with Gradients: linear interpolation looks different, but solid colors actually look the same.

Cheers,

Mika

pietblok
Offline
Joined: 2003-07-17
Points: 0

Hi Mika,

I have no experience with VolatileImages at all, but use BufferedImages quite a lot. Could the problem with color rendering have anything to do with the ColorModel, ot other attributes of the BufferedImage? How do you obtain yout BufferedImage? Do you create a compatible image?

When I need a BufferedImage I do it as follows:

[code]
if (paintDirect) {
super.paint(g2);
} else {
BufferedImage image = g2.getDeviceConfiguration()
.createCompatibleImage(clipBounds.width,
clipBounds.height,
Transparency.TRANSLUCENT);
Graphics2D g3 = image.createGraphics();
try {
g3.clipRect(0, 0, clipBounds.width,
clipBounds.height);
g3.translate(-clipBounds.x, -clipBounds.y);
g3.setColor(g2.getColor());
g3.setFont(g2.getFont());
g3.setBackground(g2.getBackground());
g3.setStroke(g2.getStroke());
g3.setPaint(g2.getPaint());
g3.setRenderingHints(g2.getRenderingHints());
super.paint(g3);
if (opacity < 1f) {
g2.setComposite(AlphaComposite.SrcOver
.derive(getOpacity()));
}
g2.drawImage(image, clipBounds.x, clipBounds.y,
null);
} finally {
g3.dispose();
}
}
[/code]

I've never seen color differences, but maybe I never used subtle colors.

Hope this helps,
Piet

mkae
Offline
Joined: 2010-04-19
Points: 0

Hi Piet,

Thanks for your interest here, I actually do create my BufferedImage from the createCompatibleImage method in a very similar way to the code you provided, so presumably there is no difference regarding the ColorModel...

Might be kind of specific anyway, that the gradients have different interpolation and/or alpha composition depending on the machine hardware... In addition Java 1.6 new gradients might not suffer from this, I should give it a try when I have time, even if Java 1.6+ was not an option for my case.

Anyway, this was solved by using VolatileImages, to ensure all areas use the same so-called rendering pipeline, even though they have a much wider purpose regarding real-time graphics and performance.

Cheers ;)

linuxhippy
Offline
Joined: 2004-01-07
Points: 0

If the differences are not minor, please file a bug about it, including video hardware and driver version.
In theory gradients should look the same regardless where rendered to.