# How can I efficiently change the color of a BufferedImage?

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?

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.