I am drawing multiple resources onto a bitmap via a canvas. I would like the end result of the composite image to have a certain alpha. Right now I'm setting paint's alpha to the level i want and then drawing each bitmap with that alpha, but i know this would create a composite image of a lot of different alphas. Is there a way to apply an alpha to the entire composite image in performance friendly manner?
You could draw all the drawables fully opaque (alpha = 255) to begin with, then draw over the entire destination Bitmap using Porter-Duff MULTIPLY mode with the right source alpha to change it all at one shot.
Related
Im using processing with java. I have a transparent background png drawing I made, it sort of looks like an abstract leaf, sort of like matisse. I know how to create shapes with random colors chosen from an array, so i can display that shape with different background colors for each frame in a loop, saving each. what I want to do next is create another layer over the drawing that is populated with a random color from my array, but to have that layer display only on the pixels from the underlying png that is loaded.
the end result is the ability to put out an endless number of randomly colored versions of that leaf design, with a random background color. I just havent figured out how to create this kind of clipping mask effect.
You can use the leaf image as a mask for the dynamically colored object. This will apply the alpha channel (transparency) to the masked image. mask operates on images, so you’ll need to draw your color fill to a PGraphics or PImage and apply the mask to that image.
Depending on the specifics of the effect you’re trying to achieve, you might also be able to simply apply a color tint to the leaf image to change to the desired color.
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:
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!
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.
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.
I'm trying to put corners im my ImageView and I find these "workarounds":
1 - Take the Bitmap soure and paint then
2 - put a second ImageView on my layout and use shape+corners as its source
It's not possible take the image view and put a corner around then?
In my app i have a List with a lot of ImageView (the Bitmap used in this ImageView's is programmatically) and I want to put corners in every ImageView.
There is any other option?
You can create a selector that contains shape with rounded corners, and then apply it as the ImageView's background using xml.
Look at this answers here
You can also do it via code by using PorterDuffXfermode. PorterDuffXfermode uses alpha compositing that will allow you to create and intersection (things of mathematical sets here) between the Canvas you get from onDraw() and an off screen Canvas you will have to create. You will use one of the PorterDuff.Mode flags to tell the framework you want to only render the pixels that intersect from the two Bitmaps in each Canvas.
More on Alpha Compositing
Looking for the least painful way to grab a Bitmap and translate every pixel of a specific color to transparent.
In particular, I have set all the pixels I want to be transparent to 0xFF00FF, but I am not seeing any native method that do this.
Do I have to actually loop through all the pixels comparing values? And if so, can I change them in place or do I need to make a new bitmap array and create a new bitmap?
Bitmaps don't have alpha channels like PNG/GIF. It's up to the application to use a transparency mask.
I have a graphics system for Java which allows objects to be "wallpapered" by specifying multiple images, which can have (relatively) complex alignment and resizing options applied.
In order to perform adequately (esp. on very low powered devices), I do the image painting to an internal image when the wallpaper is first painted, and then copy that composite image to the target graphics context to get it onto the screen. The composite is then recreated only if the object is resized so the only work for subsequent repaints is to copy the clipped region from the composite to the target graphics context.
The solution works really well, except that when I have PNG images with alpha-channel transparency the alpha channel is lost when painting the composite - that is the composite has all pixels completely opaque. So the subsequent copy to the on-screen graphics context fails to allow what's behind the wallpapered object show through.
I did manage to use an RGBImageFilter to filter out completely transparent pixels, but I can't see a solution with that to making blended transparency work.
Does anyone know of a way I can paint the images with the alpha-channel intact, and combined if two pixels with alpha values overlap?
What type of Image do you use for the composite image?
You should use a BufferedImage and set it's type to TYPE_INT_ARGB which allows translucency.