2
\$\begingroup\$

I am trying to change the color of a white BufferedImage image.

I do know that you can use .setRGB(x,y,rgb) and simply run some nested for loops and make changes to one pixel at a time. However, the problem arises when it comes to gradually changing the color instead of instantly doing so. This means I would have to run thousands of loops every runtime, completely ruining the frame rate.

My question is, is there a way to just change the color of an image right away?

\$\endgroup\$
0
\$\begingroup\$

It depends a bit on what you're specifically trying to do.

If you want to change all of the pixels to a single new color, then most likely the fastest & easiest way is something like this:

int width = 512;
int height = 512;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = image.createGraphics();
Color darkOliveGreen = new Color(85, 107, 47);
g2d.setColor(darkOliveGreen);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());

Note, the above code can also be modified to deal with rectangular subsections of the image.

On the other hand, if you need to quickly evaluate & process the pixels individually for some reason (i.e. change the reds to greens, the greens to blues & the blues to reds), then you'll need to manually access the data buffer that backs the image:

byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();

From there you can manipulate the pixels quickly without the overhead of issuing a method call for each read & write. The downsides to this approach are:

\$\endgroup\$
1
  • \$\begingroup\$ Using fillRect()... such a creative solution. Thanks for your help! \$\endgroup\$ Sep 7 '18 at 21:58
2
\$\begingroup\$

I think one solution is to use Graphics2D#setXORMode(Color) but I do not know if it will increase performance, since it requires you to create a new BufferedImage. Probably worth a shot, though:

public BufferedImage tintImage(BufferedImage image, Color color) {
    BufferedImage tintedImage = new BufferedImage(
                                    image.getWidth(), 
                                    image.getHeight(),
                                    BufferedImage.TYPE_INT_ARGB);

    Graphics graphics = tintedImage.createGraphics();
    graphics.setXORMode(color);
    graphics.drawImage(image, 0, 0, null); // NOT 'tintedImage'
    graphics.dispose();
    return tintedImage; // Image will be tinted
}

This is all from memory & javadoc so if that code does not work try to change these things:

  • Set color alpha to 0 (color = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0)).
  • Change BufferedImage.TYPE_INT_ARGB to BufferedImage.TRANSLUCENT.
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .