multiply an image with a color

hello,

how can i multiply an image with a color
i tried
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
but that seems to make all of the image the new color.

example multiply an image by red.
black -> black
white -> red
transparent -> transparent

thanks!

You’ll be wanting to perform a color composite, rather than an AlphaComposite.
Java2D doesn’t provide any classes to do this straight away, however it does provide the Composite interface - a framework through which this can be achieved.

Through Google I found this very thorough implementation :-

http://www.koders.com/java/fid59076705B36EA25B7F6FC9AEA08347E6B6A05564.aspx
I believe you want the MultiplyComposite subclass. ( http://www.koders.com/java/fidC5A6840364E8EC386B3AD41AACA28E0CA46E1D5D.aspx )

Obviously you shouldn’t copy/paste their code - I imagine there is a download link to the packaged library somewhere on that site.

Or you can do it manually;


                int w=image.getWidth(null);
		int h=image.getHeight(null);

		int[] pixels=new int[w*h];
		PixelGrabber pixelGrabber = new PixelGrabber(image,0,0,w,h,pixels,0,w);
		try {
			pixelGrabber.grabPixels();
		}
		catch (InterruptedException e) {}
		catch (ArrayIndexOutOfBoundsException aiobe) {}

		for (int i=0;i<pixels.length;i++)
		{
			int p=pixels[i];
			if ((p&0xff000000)!=0)
			{
				int r=Math.min(((p>>16)&0xff)+32,255);
				int g=Math.min(((p>>8)&0xff)+0,255);
				int b=Math.min((p&0xff)+0,255);
				pixels[i]=(p&0xff000000)|r<<16|g<<8|b;
			}
		}

		MemoryImageSource mis=new MemoryImageSource(w,h,pixels,0,w);
		Image newImage=Toolkit.getDefaultToolkit().createImage(mis);

this is some 7 years old code from me (thats the reason for not following code conventions…)
I can tidy it up if you want to :wink:
int[] m is the argb array of the raster and the parameter f defines the ‘strength’ of the color mix.


public static final int
R=0x00ff0000,
G=0x0000ff00,
B=0x000000ff;

int alpha(int c,int t){return(c&0x00ffffff|(t<<24));}
	
void mix(int[] m,int c, double f) {
		int ad = (int) (255 * f);
		int d = c;
		int As = 255 - ad;
		int adr = ad * (d & R);
		int adg = ad * (d & G);
		int adb = ad * (d & B);
		for (int i = 0; i < m.length; i++) {
			int s = m[i];
			int a = s >>> 24;
			m[i] = ((As * (s & R) + adr) >> 8) & R | ((As * (s & G) + adg) >> 8) & G | ((As * (s & B) + adb) >> 8) & B;
			m[i] = alpha(m[i], a);
		}
	}

thanks guys! the color composite version seems to be the best in terms of performance!