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?

up vote 0 down vote accepted

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:

  • Using fillRect()... such a creative solution. Thanks for your help! – Sublime Noob Sep 7 at 21:58

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.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.