This tutorial will show you how to convert a color image to a gray scale image in Java. In Java, there are a number of ways to convert a color image to gray scale. This tutorial will show you three ways convert the image including output quality and performance.
For reference, below is the color image that was converted:
Changing the Color Space
One way to convert a color image to gray scale, is to change the color space of the image. The sample code below shows how to change the color space:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
BufferedImage image = op.filter(bufferedImage, null);
Performance: Poor (approx. 60ms)
Image Results: Poor
Drawing to a Grayscale BufferedImage
The easiest way to convert a color image to a gray scale image is to simply draw the color image to a gray scale BufferedImage. The sample code below shows how to draw the colored image to a gray scale BufferedImage:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
Graphics g = image.getGraphics();
g.drawImage(colorImage, 0, 0, null);
g.dispose();
Performance: Good (approx. 9 ms)
Image Results: Best
Using the GrayFilter
The final way to convert a color image to a gray scale image is to use the GrayFilter. In order to use the GrayFilter, the color image must either be an ImageProducer or a BufferedImage (use the getSource() method to get the ImageProducer). The sample code below shows how to use the GrayFilter:
ImageFilter filter = new GrayFilter(true, 50);
ImageProducer producer = new FilteredImageSource(colorImage.getSource(), filter);
Image mage = this.createImage(producer);
Performance: Best (approx. 1 ms)
Image Results: Good. When constructing the GrayFilter, you can control the brightness of the grays with the second parameter.
Which Method Should You Use
The low quality and slow performance, should rule out using the ColorSpace method. If you need the best performance and can live with the image quality, the GrayFilter would be the option for you. Drawing to a gray scale BufferedImage is the overall best option, it is only a few milliseconds slower than the best, the image quality is the best, and the code is the simplest.