android: How to implement hardware accelerated image eraser? - android

I have a bitmap whiteboard app drawing above an imageview background. When I draw a CLEAR paint on top
mo_ink.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
or any PorterDuff method, the rendering has a horrible black border while drawing. Disabling hardware acceleration makes the app unusable.
How can I implement a background eraser without the hardware rendering errors?
Edit: I have that slightly wrong. PorterduffMOde CLEAR draws a black path that renders clear on completion. Any other Porterduff method I've tried renders a black bounding box around the path. Ideally I'd like the drawn line to be immediately transparent, drawing the background bitmap masked to the path, but applying a suitable shader would result in the black border. Any solutions? I can't work out what Rasterizer does or if it'll help!

Related

How to implement a real eraser in my drawing app?

I am creating a simple drawing app using kotlin. I want to implement an eraser and was not able to find any proper solution for this. Every solution either uses white color as a substitute for eraser or completely resets the canvas after clicking on eraser button. As I have also implemented the feature of importing background images from the gallery, I can't use white color as eraser.
There is no magic eraser in canvas, because erasing is nothing but drawing something onto the canvas. You can't set the paint color to Transparent and draw on canvas to erase what is already drawn. This simply draws something that is transparent, which is basically nothing.
So you will need to implement an eraser by using a Color. Normally this is white, because the background is usually set to white. So this gives the appearance of erasing the content.
In your case, you have a background image. To implement an eraser for this, you will need 2 canvas. The background image will be drawn in the 1st canvas. All the other content (drawCircle, drawRect, drawPath, etc...) are drawn onto the 2nd canvas. Now, you could take the bitmap out of the 2nd canvas and draw that in the 1st canvas (drawBitmap). This gives the final appearance.
Now, in this setup, you could use "White" as a color to erase from the 2nd canvas. While drawing 2nd canvas content onto the 1st, use one of the PorterDuff mode, so that the "White" goes away.

Android draw transparency

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.

On an android Canvas, how do I draw overlapping shapes with non-interacting alphas?

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.

Android: image doesn't keep it's original color with use of canvas.drawBitmap

I'm developing an android app and I'm facing a weird issue.
I'm doing some image processing on a SurfaceView. I'm drawing the processed image using a canvas and the following method:
canvas.drawBitmap(image, x, y, paint)
My SurfaceView has a colored background (#3500ffff, kind of very dark green) and once the image is drawn, I can notice that its original colors are not conserved. It has a very slight dark green tint, like if the bitmap alpha was changed.
Did anyone already encounter this issue? Would you have an idea on how to fix this?
This would happen with a 16 bits destination. 16 bits buffers encode pixels in 565 format, which gives you a higher precision in the green channel, which sometimes result in greenish tints. A 32 bits destination/bitmap would solve this issue.
Presuming that your image is not transparent how did you define paint, it should not be a transparent colour or use some special effect. Try using null for paint.
The other thing is what are you drawing first the image or the background? Just wondering if your drawing order is correct.
If you set your surface to be non-transparent will the image change colour then?
Another thing I noticed which I think is connected with events sychronisation is that sometimes drawing on surface creates a semi-transparent sprite when moving the finger very fast over the screen which initialises drawing.

Android draw with blur

I need do draw on Android's Canvas using Blur effect,
it is a very simple feature,
I need to draw a circular area, which is blurred (the foreground) and the background transparent, I can do everything with manipulating the colour alpha to do it with custom transparency but I need it to be blurred instead of transparent..
any ideas?
(For those who are coming back, though this is an old question)
On the Paint object which you are using to draw the Color, set
paint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL))
Then, in Android Manifest.xml, set
android:hardwareAccelerated="false"
for your activity
(Blur doesn't work when hardware acceleration is true)
For more explanation refer
Android BlurMaskFilter has no effect in canvas.drawOval while text is blurred
If you're not gonna need to manipulate it afterwards you could just draw to a buffer and blur it yourself pixel by pixel, then blit that buffer to screen when you need to paint it.
Or this: http://developer.android.com/reference/android/graphics/BlurMaskFilter.Blur.html
Take a look at this: Android, Blur Bitmap instantly?
Again I would recommend you first to draw into a bitmap. Scale it down (try different sizes), and the scale it back up to the original size (either as a new bitmap or if you use hw acceleration do it while you draw).

Categories

Resources