JAI Add Alpha Channel to RenderedImage

582 views Asked by At

I have two RenderedImages. I want to do an Overlay Operation with these two images and therefore they need to match in data type and the number of bands.
The problem I have is that one image has 3 bands (RGB) and the second image has 4 bands (ARGB).

My question is how can I add an Alpha Channel to the first image so I can do the Overlay Operation?

EDIT
Ok, I found a method of adding an Alpha Channel to the first image. Below is the code. I simply created a single banded constant image and merged it with my first image.

ParameterBlock pb = new ParameterBlock();
pb.add(new Float(finalImage.getWidth())).add(new Float(finalImage.getHeight()));
pb.add(new Byte[] {new Byte((byte)0xFF)});
RenderedImage alpha = JAI.create("constant", pb);

finalImage = BandMergeDescriptor.create(finalImage, alpha, null);

The problem I have now is that everytime I add an overlay the image changes colors. All the colors become nuances of red or pink. When I add a second overlay, the image becomes normal again, but the first overlay changes colors. All black areas become white.

Also the background of the overlay is not transparent. It is grey.

Below are examples of the images, so you see how the change colors:

original Picture

after adding the first overlay

after adding the second overlay

As you can see, the picture and overlays change colors and the background of the overlay isn't transparent.

Can you help me solve this problem, so that the image is always displayed correctly? Thanks!

2

There are 2 answers

2
cello On

You can try to create a new BufferedImage with ARGB-model, and just paint the non-transparent background picture into this new BufferedImage. Then you have a BufferedImage with alpha-channel (although all of the pixels are opaque), so the Composition should hopefully work.

0
Patrick Anderson On

im not sure about TYPE_4BYTE_ARGB as I usually work with BufferedImages of TYPE_INT_ARGB but I have often used the method of drawing a RGB BufferedImage to a new ARGB BufferedImage and then drawing that onto other things without problem. the change in color would suggest an unwanted change is being made to the other channels in the overlay process as it doesn't seem to be specific to a specific image. If your overlay operation is similar to drawing one image onto another with alpha I would probably suggest using the Graphics.drawImage()/drawRenderedImage() method for the overlay itself not to mention the background should not even need alpha in this case.

the code:

public RenderedImage overlay(RenderedImage back, RenderedImage front, AffineTransform overlayTransformation)
{

    BufferedImage newBack = new BufferedImage(back.getWidth(), back.getHeight(), TYPE_3BYTE_RGB);
    newBack.setData(back.getData());
    Graphics2D graphics = (Graphics2D)(newBack.getGraphics());
    graphics.drawRenderedImage(front, overlayTransformation);
    return newBack;

}

you may want to ensure the original back Raster is not modified though.