I'm writing an Android app that involves some 2D drawing operations. I am trying to use saveLayer and xfermode SRC_IN to draw the intersection of 2 images. It seems to work OK if I don't rotate anything, but if I rotate one of the images, it seems to treat the pixels outside the rotated rectangle bounding the image as opaque (part of the intersection), or more likely, as not part of the drawing operation (unaffected by the transparent pixels laid on top of it).
Below is a picture of what I'm talking about. The "5" and "3" images near the bottom are being "intersected" by drawing the "3" image (rotated) with xfermode SRC_IN on the "5". I have shown all three images on a gradient background to help visualize transparency.
After some thought, I suspect that the area outside the clipping rectangle of the "3" is not being treated as opaque, but rather simply not being treated as part of the drawing operation. What's interesting is that if I mark the layer as a software layer instead of a hardware layer the while number "5" shows up in the background instead of just the parts outside 3's clipping rectangle. I don't understand this.
How is the area affected by an SRC_IN drawing operation determined? (Normally it doesn't matter, but one unique feature of SRC_IN is that it has to turn opaque pixels transparent based on what is transparent in the image being drawn, so the overall size of that is drawn is important even though it normally wouldn't be.) How can I make the pixels outside the drawn area of the 3 be treated as not part of the intersection? Do I need to enlarge the clipping rectangle that is active when drawing the 3?
Related
I want to apply the border to this custom view shape
which created by many canvas.draw...() in onDraw()
The border that i want to create and apply to my custom view should have equal range all the way with some distance from the custom view and it should also cover small circle in each slice.
Any idea how to make this?
Thanks.
This isn't so much an answer, but more of a recommendation. Take a look at the Porter-Duff modes available to you. Worst case you may need to do some per pixel image manipulation which should be fine as long as the view isn't animated.
On second thought, here's an idea: why not create two images: one large circle which will always draw behind everything and a second which will always draw behind the small circles. The large circle would just be the complete border you want displayed, whereas the small circles would actually only be a semi circle border, which would render on top of the large circle (covering the large circle border under it). The key would then be to rotate the small border circle depending on where it's located. I hippie that makes sense, but it should work and be very efficient too.
Another option would be to separate the rendering into white circles and slightly larger border color circles. If you render the slightly larger (border color) circles first, then render the normal circles (white) on top, then you won't have to worry about any rotations and it will render correctly if the small outer circles begin to overlap.
So the idea is similar to the first suggestion. You'll still need a large circle and small circle (both white), but in addition, you'll need slightly larger border colored large and small circles.
I hope this description is a little clearer, but I assume that you are comfortable enough with compound drawables to figure out the rest, given that you've gotten this far in making your view.
All the best implementing it, and feel free to ask for any clarification! :)
I'm new to Android (and Java for that matter), and I'm making a simple game. I'm stuck.
My problem is this:
I have 2 png images (a background and foreground) that take up the whole screen on startup. I now want to be able to set the width of the "drawn portion" of the foreground to the x-coordinate of ON_DRAG. My control method works fine; it's used like this:
g.drawRect(0, 0, scene.getLine(), g.getHeight(), Color.GREEN);
where scene.getLine() returns the x-value of the touch. So at this point I can draw a green rectangle above my images. But what I actually want is for those rectangle dimensions to "punch a hole" in my top-layer png (so the background is revealed beneath). I do not want to scale the foreground.
I have tried clipRect, but it doesnt work because I have other images that need to be drawn on top of these two, and clipRect prevents this. I have looked at a bunch of "PorterDuffXfermode" code, but cannot understand how to apply it to my situation, and cannot make it work. i.e. I can make a Paint with the PorterDuff "SRC" mode set, but I dont know how to define "source" and "destination" images so the Paint will work its magic. A final consideration with this is that even if the PorterDuff would work, Im not sure it would be practical given that I want this thing to run at 60fps.
Any suggestions?
Thanks.
You can call canvas.save() before a clip and canvas.restore() after your drawing to return the canvas to the sate it was in before you stared. Then you can draw your additional images.
The game I am writing has two layers. The first is the background layer, which I draw by texturing a background image onto a polygon. The second level has a small polygon (representing a ball) that moves around the screen on top of the background layer.
When I texture a PNG of a ball onto the small polygon (second layer), the texture is drawn, but the rest of the small polygon is black. I want the black behind the ball to be transparent, so that you can see the background behind it. In other words, every pixel on the polygon that is not part of the ball needs to be transparent.
I have experimented with blending, but with no success.
How can I accomplish this?
Enable blending when drawing the ball. The ball PNG must have an alpha channel and be transparent at the desired places.
glDisable(GL_BLEND);
draw_background();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
draw_ball();
On an android Canvas, if I draw a circle with alpha 0xCC and color Color.RED and then draw another circle which partially overlaps the first circle with the same parameters, I'll end up with a venn diagram.
Here is a random example I found (just ignore the [Text] in there). I want to draw overlapping circles like in this diagram, but I don't want the center to be darker, but I do want the whole thing to have alpha so that the map underneath is visible.
Is there a way to do this directly or do I need to draw to a bitmap without alpha and then set the alpha for the whole bitmap and draw it to a canvas? (I haven't used bitmaps yet, so I am not sure how they are used yet.)
The easy way would be your suggested solution, ie. drawing all circles with no alpha to a bitmap, then draw that bitmap to another one using the desired alpha.
The hard way would be using blend modes, specifically PorterDuff.Mode in Android. An example can be found here.
I need to draw a bitmap on top of a completely rendered GLSurfaceView. By completely rendered I mean that the entire thing is filled with colorized triangles. Obviously the bitmap will hide the triangles underneath it, but I would like to minimize how much is hidden.
The bitmap is 64x64 pixels and has many empty areas that are translucent in the PNG file. When I draw the bitmap by making a square with two triangles, the translucent areas become black (the green areas in the picture above), perhaps because the app background is black. Is there an easy way to get the translucent areas to not affect the image (the second image above)? Do I need to create a complex set of triangles that exactly outlines the non-translucent parts when I render the bitmap?
I am developing on a Motorola Xoom, Android 3.0. Thanks for your time.
Use the alpha test.