This issue came about as I was trying to test a routine for converting images to grayscale. The code below creates a horizontal strip of coloured squares and then uses two different methods to create grayscale images. The fist pastes the original into a grayscale buffered image. The second converts the colours to shades of gray and then draws them on a "colour" BufferedImage.
The two grayscale images use visibly different shades of gray. What is surprising is that both of my methods to do the conversion make API calls that look like they should produce the same results.
Can anyone shed light on the discrepancy?
If it helps, I'm not well-versed in ColorModel or ColorSpace so it is possible I have used them incorrectly.
My mistake. That was referring to a third method I have not included here.
The two grayscale images use visibly different shades of gray. What is surprising is that both of my methods to do the conversion make API calls that look like they should produce the same results.
Can anyone shed light on the discrepancy?
My mistake. That was referring to a third method I have not included here.
import java.awt.*; import java.awt.image.*; import java.util.*; import java.util.List; import javax.swing.*; @SuppressWarnings("serial") public class GrayscaleDemo extends JFrame { public static void main(String[] args) { @SuppressWarnings("unused") GrayscaleDemo grayscaleDemo = new GrayscaleDemo(); } private Image fullColour; private Image convertedToGray; private Image alwaysGray; public GrayscaleDemo() { super("Grayscale Demo"); setDefaultCloseOperation(EXIT_ON_CLOSE); makeImages(); makeLayout(); setAsVisible(); } private void makeImages() { Color[] colours = {Color.red, Color.green, Color.blue, Color.black, Color.gray, Color.white}; Color[] grays = colourArrayToGray(colours); fullColour = makeColourStrip(colours); convertedToGray = imageToGray(fullColour); alwaysGray = makeColourStrip(grays); } private Color[] colourArrayToGray(Color... cols) { List<Color> result = new ArrayList<>(); for(Color c : cols) { Color gray = singleColourToGray(c); result.add(gray); } return result.toArray(new Color[cols.length]); } private static Color singleColourToGray(Color c) { BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2 = image.createGraphics(); g2.setColor(c); g2.fillRect(0, 0, 1, 1); g2.dispose(); Color result = new Color(image.getRGB(0, 0)); return result; } private Image makeColourStrip(Color... cols) { final int squareSize = 50; int width = cols.length * squareSize; BufferedImage result = new BufferedImage(width, squareSize, BufferedImage.TYPE_3BYTE_BGR); int x1 = 0; Graphics2D g2 = result.createGraphics(); for(Color c : cols) { g2.setPaint(c); g2.fillRect(x1, 0, squareSize, squareSize); x1 += squareSize; } g2.dispose(); return result; } private BufferedImage imageToGray(Image im) { BufferedImage result = new BufferedImage(im.getWidth(null), im.getHeight(null), BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2 = result.createGraphics(); g2.drawImage(im, 0, 0, null); g2.dispose(); return result; } private void makeLayout() { int rows = 0; int cols = 1; setLayout(new GridLayout(rows, cols)); addImage(fullColour); addImage(convertedToGray); addImage(alwaysGray); pack(); } private void addImage(Image im) { JLabel label = new JLabel(new ImageIcon(im)); add(label); } private void setAsVisible() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { setVisible(true); } }); } }