I do not know if there is a built-in function for cycling colors in an image. I think it should be, but I could not find it.
In any case, one way to do this is to cycle through all the pixels of the image, search for colors in a predefined list of colors, from bright to dark, and make each pixel βdarkerβ.
public static void shiftToBlack(BufferedImage img) { // the four colors used in test.png, from bright to dark List<Integer> colors = Arrays.asList(-196868, -4088073, -10112268, -12500653); for (int i = 0; i < img.getRaster().getWidth(); i++) { for (int k = 0; k < img.getRaster().getHeight(); k++) { int c = img.getRGB(i, k); int index = colors.indexOf(c); int c2 = index < colors.size() - 1 ? colors.get(index+1) : c; img.setRGB(i, k, c2); } } }
Of course, this does not scale well when the image is larger, but for a typical Game Boy four-color screen, this should work. Thus, if you apply any filters, such as enlarging the image for playback on modern screens or smoothing, you must apply them after this color change operation. In addition, you will have to adapt colors to the four colors used in your images.
Full example code:
BufferedImage img = ImageIO.read(new File("test.png")); JComponent component = new JComponent() { protected void paintComponent(Graphics graphics) { graphics.drawImage(img, 0, 0, null); }; }; component.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { shiftToBlack(img); component.repaint(); } }); JFrame frame = new JFrame("test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(component); frame.pack(); frame.setSize(150, 150); frame.setVisible(true);
And my test.png

source share