I was looking at the ImageConverter class, trying to figure out how to convert a BufferedImage to 8-bit color, but I have no idea how I would do this. I was also searching around the internet and I could find no simple answer, they were all talking about 8 bit grayscale images. I simply want to convert the colors of an image to 8 bit... nothing else, no resizing no nothing. Does anyone mind telling me how to do this.
Asked
Active
Viewed 9,186 times
11
-
You probably have to choose a quantization algorithm, ie. something that transform the range of colors of your images into a 256 entry palette. – PhiLho Jun 16 '12 at 09:01
-
What do you mean by converting the colors of an image to 8-bit? I guess you want to reduce the color space? Do you want to perform Color quantization? – Behe Jun 16 '12 at 09:05
-
Could you guys point me to a library/API of some sort? I have no idea what you're talking about. That also sounds like I would be able to create my own palette which would be event better if possible. – Zach Sugano Jun 16 '12 at 09:08
3 Answers
5
You can use JAI (Java Advanced Imaging), the official Sun (now Oracle) image library to do that.
The ColorQuantizerDescriptor shows the choice of quantization processes you can apply.

PhiLho
- 40,535
- 6
- 96
- 134
-
Do you have some sample code? http://stackoverflow.com/questions/15312921/how-to-use-colorquantizerdescriptor – Daniel Trebbien Mar 09 '13 at 16:18
3
This code snippet from the article "Transparent gifs in Java" at G-Man's Uber Software Engineering Blog works well:
public static void main(String[] args) throws Exception {
BufferedImage src = convertRGBAToIndexed(ImageIO.read(new File("/src.jpg")));
ImageIO.write(src, "gif", new File("/dest.gif"));
}
public static BufferedImage convertRGBAToIndexed(BufferedImage src) {
BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
Graphics g = dest.getGraphics();
g.setColor(new Color(231, 20, 189));
// fill with a hideous color and make it transparent
g.fillRect(0, 0, dest.getWidth(), dest.getHeight());
dest = makeTransparent(dest, 0, 0);
dest.createGraphics().drawImage(src, 0, 0, null);
return dest;
}
public static BufferedImage makeTransparent(BufferedImage image, int x, int y) {
ColorModel cm = image.getColorModel();
if (!(cm instanceof IndexColorModel))
return image; // sorry...
IndexColorModel icm = (IndexColorModel) cm;
WritableRaster raster = image.getRaster();
int pixel = raster.getSample(x, y, 0); // pixel is offset in ICM's palette
int size = icm.getMapSize();
byte[] reds = new byte[size];
byte[] greens = new byte[size];
byte[] blues = new byte[size];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
return new BufferedImage(icm2, raster, image.isAlphaPremultiplied(), null);
}

creemama
- 6,559
- 3
- 21
- 26
2
You can use the convert8
method in the ConvertUtil
class.
For details have a look here.

JHS
- 7,761
- 2
- 29
- 53
-
I could not use ConvertUtil.convert8, so I would have to import that class, but I could not find what the import code was. Do you by chance do what/where it is? – Dak31 Nov 23 '16 at 00:08