-
Bug
-
Resolution: Unresolved
-
P4
-
6u45, 7, 7u72, 8, 8u45, 9
-
x86_64
-
generic
FULL PRODUCT VERSION :
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
java version "1.7.0_72"
Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.72-b04, mixed mode)
Probably others.
ADDITIONAL OS VERSION INFORMATION :
0S X 10.9.5
Linux SCBD013 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Probably all others.
A DESCRIPTION OF THE PROBLEM :
Wrong pixel colors are selected in buffered images created with the constructor:
BufferedImage(int width, int height, int imageType, IndexColorModel cm)
when the indexed color model contains translucent colors
(or maybe when it contains colors differing only in the alpha value).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test application attached.
It produces two 256x256 images 'image0.png' and 'image1.png',
using an indexed color model of 256 alpha varying blue colors: from RGBA (0,0,255,0) to (0,0,255,255).
The images are column-wise filled with the colors of the indexed color model.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both images should be equal: a gradient from fully transparent blue to fully opaque blue.
ACTUAL -
Columns 0-254 of 'image0.png' are wrong: pixels are fully transparent,
so the first color in the indexed color model is used.
This suggests that the alpha component of the colors in the color model
is not considered in the indexed color look up.
Please note that this only happens when using the image constructor with size,
image type and color model arguments.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
public class TestTranslucentIndexColorModel {
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO Auto-generated method stub
final int width = 256;
final int height = 256;
final IndexColorModel colorModel = createColorModel(width);
final BufferedImage image0 = new BufferedImage(width, height,
BufferedImage.TYPE_BYTE_INDEXED,
colorModel);
gradientfill((Graphics2D) image0.getGraphics(), width, height, colorModel);
final File file0 = new File("image0.png");
ImageIO.write(image0, "png", new FileImageOutputStream(file0));
final byte[] pixels = new byte[width * height];
final DataBuffer buf = new DataBufferByte(pixels, pixels.length);
final SampleModel sampleModel = colorModel.createCompatibleSampleModel(width, height);
final WritableRaster raster = Raster.createWritableRaster(sampleModel, buf, null);
final BufferedImage image1 = new BufferedImage(colorModel, raster, false, null);
gradientfill((Graphics2D) image1.getGraphics(), width, height, colorModel);
final File file1 = new File("image1.png");
ImageIO.write(image1, "png", new FileImageOutputStream(file1));
}
private static IndexColorModel createColorModel(int length) {
if (length < 0 || length > 256)
throw new IllegalArgumentException("too many colors");
byte[] r = new byte[length];
byte[] g = new byte[length];
byte[] b = new byte[length];
byte[] a = new byte[length];
for (int i = 0; i < length; i++)
{
r[i] = (byte) 0;
g[i] = (byte) 0;
b[i] = (byte) 255;
a[i] = (byte) i;
}
return new IndexColorModel(8, length, r, g, b, a);
}
private static void gradientfill(Graphics2D g2, int w, int h, IndexColorModel cm) {
for (int i = 0; i < h; i++)
{
g2.setColor(new Color(cm.getRGB(i), cm.hasAlpha()));
g2.fillRect(i, 0, 1, h);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As the test code shows, the problem does not occur when the alternative image constructor is used.
However the code is longer and dirtier to get to the same (expected) results.
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)
java version "1.7.0_72"
Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.72-b04, mixed mode)
Probably others.
ADDITIONAL OS VERSION INFORMATION :
0S X 10.9.5
Linux SCBD013 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Probably all others.
A DESCRIPTION OF THE PROBLEM :
Wrong pixel colors are selected in buffered images created with the constructor:
BufferedImage(int width, int height, int imageType, IndexColorModel cm)
when the indexed color model contains translucent colors
(or maybe when it contains colors differing only in the alpha value).
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test application attached.
It produces two 256x256 images 'image0.png' and 'image1.png',
using an indexed color model of 256 alpha varying blue colors: from RGBA (0,0,255,0) to (0,0,255,255).
The images are column-wise filled with the colors of the indexed color model.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Both images should be equal: a gradient from fully transparent blue to fully opaque blue.
ACTUAL -
Columns 0-254 of 'image0.png' are wrong: pixels are fully transparent,
so the first color in the indexed color model is used.
This suggests that the alpha component of the colors in the color model
is not considered in the indexed color look up.
Please note that this only happens when using the image constructor with size,
image type and color model arguments.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
public class TestTranslucentIndexColorModel {
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO Auto-generated method stub
final int width = 256;
final int height = 256;
final IndexColorModel colorModel = createColorModel(width);
final BufferedImage image0 = new BufferedImage(width, height,
BufferedImage.TYPE_BYTE_INDEXED,
colorModel);
gradientfill((Graphics2D) image0.getGraphics(), width, height, colorModel);
final File file0 = new File("image0.png");
ImageIO.write(image0, "png", new FileImageOutputStream(file0));
final byte[] pixels = new byte[width * height];
final DataBuffer buf = new DataBufferByte(pixels, pixels.length);
final SampleModel sampleModel = colorModel.createCompatibleSampleModel(width, height);
final WritableRaster raster = Raster.createWritableRaster(sampleModel, buf, null);
final BufferedImage image1 = new BufferedImage(colorModel, raster, false, null);
gradientfill((Graphics2D) image1.getGraphics(), width, height, colorModel);
final File file1 = new File("image1.png");
ImageIO.write(image1, "png", new FileImageOutputStream(file1));
}
private static IndexColorModel createColorModel(int length) {
if (length < 0 || length > 256)
throw new IllegalArgumentException("too many colors");
byte[] r = new byte[length];
byte[] g = new byte[length];
byte[] b = new byte[length];
byte[] a = new byte[length];
for (int i = 0; i < length; i++)
{
r[i] = (byte) 0;
g[i] = (byte) 0;
b[i] = (byte) 255;
a[i] = (byte) i;
}
return new IndexColorModel(8, length, r, g, b, a);
}
private static void gradientfill(Graphics2D g2, int w, int h, IndexColorModel cm) {
for (int i = 0; i < h; i++)
{
g2.setColor(new Color(cm.getRGB(i), cm.hasAlpha()));
g2.fillRect(i, 0, 1, h);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
As the test code shows, the problem does not occur when the alternative image constructor is used.
However the code is longer and dirtier to get to the same (expected) results.