Tinting Images

I have a set of images which I want to tint with different colors.
I know I can make the whole image gray with this code:

BufferedImage source = …;

BufferedImageOp op = new ColorConvertOp( ColorSpace.getInstance(ColorSpace.CS_GRAY), null);

op.filter(source, source);

This will result in the image being tinted with different shades of gray.

Is there any way to do this with another color other than gray?

Thanks.

Get the pixel data, convert from RGB to HSL, change the hue, convert from HSL to RGB and then you write those changed pixels into a new image.

The result can be something like:

http://kaioa.com/k/bricksheet.png

The first one is the original and the rest is generated. It’s a full cycle… one more and I would be back to the original colors again.

You could also change the color in other color spaces, but HSL has the advantage that you only need to change the hue and you get somewhat intuitive results. Unlike HSB/HSV it won’t change saturation or lightness. The behavior is generally a lot closer to what one would expect.

Is there any way of doing this to an entire graphics context instead of a specific image?
I’m looking for something like a customized Composite.

I have this snippet:

public class TintingComposite implements Composite
{

int m_r;
int m_g;
int m_b;

double m_newColorPercentage; // 0-1
double m_oldPercentage;//0-1

public TintingComposite(Color a_color, double a_dPercentage)
{
m_newColorPercentage = a_dPercentage;
m_oldPercentage = 1 - m_newColorPercentage;

m_r = (int) (a_color.getRed() * m_newColorPercentage);
m_g = (int) (a_color.getGreen() * m_newColorPercentage);
m_b = (int) (a_color.getBlue() * m_newColorPercentage);

}

public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel,
RenderingHints hints)
{

return new CompositeContext()
{

  public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
  {
    for (int x = 0; x < dstOut.getWidth(); x++)
    {
      for (int y = 0; y < dstOut.getHeight(); y++)
      {
        // Get the source pixels
        int[] srcPixels = new int[4];
        src.getPixel(x, y, srcPixels);
        
        //blend in the new r,g,b but keep the alpha
        srcPixels[0] = (int) (srcPixels[0] *
                              m_oldPercentage + m_r) & 0xff;
        srcPixels[1] = (int) (srcPixels[1] *
                              m_oldPercentage + m_g) & 0xff;
        srcPixels[2] = (int) (srcPixels[2] *
                              m_oldPercentage + m_b) & 0xff;
        dstOut.setPixel(x, y, srcPixels);
      }
    }
  }

  public void dispose()
  {
  }
};

}
}

The only problem is that I whenever I try to set a pixel which has an alpha different from 1, I end up making it opaque.
I suspect my problem is that when I call dstOut.getNumBands() it returns 3 while src.getNumBands() returns 4.

Any idea? Alternatives?
Thanks.