0

I am animating a simulation, and the images I'm using for my entities are small PNG files that are in black and white (if that makes any difference). I would like to know if there is any way to change the color of the image (e.g. change the black to red, or overlay a red filter over the black) once it's been imported as a BufferedImage? Or is my best bet to rather create separate color versions of the icon outside of Java and importing them as separate images?

Martin
  • 277
  • 2
  • 5
  • 17
  • http://stackoverflow.com/questions/23763/colorizing-images-in-java – PeterMmm Jan 10 '14 at 10:06
  • If you are dealing with actual images then I would assume that using separate colored versions of the image would be **easier**, that being said I'm not saying your way is impossible, it is probably a lot harder to implement though. – Ceiling Gecko Jan 10 '14 at 10:06
  • See [Working with Images](http://docs.oracle.com/javase/tutorial/2d/images/index.html). You might find something useful. – Paul Samsotha Jan 10 '14 at 10:23
  • What does this have to do with Swing? Given you might do it the same way in a desktop app. as a command line app., I'm thinking 'nothing'. – Andrew Thompson Jan 10 '14 at 11:23

1 Answers1

2

you can use the java.awt.image.RGBImageFilter class

I personally haven`t played with that, I went another way, which is getting the icon into an array of pixels(ints) and manipulating this on my own.

With that , you can create an instance of ImageSourceInt (as I call it) passing an ImageIcon, fiddling around with it

(canvasData is the pixels-array in ARGB-int format - 1byte per channel each = 4 bytes = 1 int)

and retrieve a BufferedImage (a view, not a copy) back for use with Swing.

For the latter, call the getReferenceImage() method.

By the way, if you dont know about scanSize (common term in imaging) the just consider it as the width of the image.

(Sorry for the bad code formatting, I`m new here)

public class ImageSourceInt implements ImageSource {

int[] canvasData;

int width;

int height;

int scanSize;

int lineCount;


/**
 * @param source make sure it is loaded or this ImageSource will be empty.<br>
 * sizeIncrementWidth and sizeIncrementHeight are set to 1
 */
public ImageSourceInt(ImageIcon source){
    if (source == null) {
        this.canvasData = new int[0];
        return;
    }
    this.width = source.getIconWidth();
    this.height = source.getIconHeight();
    this.scanSize = source.getIconWidth();
    this.lineCount = source.getIconHeight();

    this.canvasData = new int[this.width*this.height];

    // PixelGrabber(Image img, int x, int y, int w, int h, int[] pix, int
    // off, int scansize)
    PixelGrabber grabber = new PixelGrabber(source.getImage(), 0,
            0, this.width, this.height, this.canvasData, 0, this.scanSize);
    try {
        grabber.grabPixels();
    } catch (InterruptedException e) {
        e.printStackTrace();// must not be...
    }
}

/**
 * @return a BufferedImage with the data of this ImageSource (referenced)<br>
 * IMPORTANT: if the size changed, the BufferedImage will get invalid, causing strange effects or exceptions
 */
public BufferedImage getReferenceImage(){
    DataBuffer buf = new DataBufferInt(this.canvasData, this.canvasData.length);
    WritableRaster wRaster = Raster.createPackedRaster(buf, this.getWidth(), this.getHeight(), this.getScanSize(), 
            new int[]{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, new Point());
    BufferedImage bi = new BufferedImage(ColorModel.getRGBdefault(), wRaster, false, null);
    return bi;
}

}

Flo
  • 71
  • 2