How can I erase the canvas content? - android

I´m trying to let the background transparent in a sequence of frames painted in Canvas in Android 2.2.
But it seems that the background does not erase the old frame when a new frame is painted.
How can I erase it?

How do I clear (or redraw) the WHOLE canvas for a new layout (= try at the game) ?
Just call Canvas.drawColor(Color.BLACK), or whatever color you want to clear your Canvas with.
And: how can I update just a part of the screen ?
There is no such method that just update a "part of the screen" since Android OS is redrawing every pixel when updating the screen. But, when you're not clearing old drawings on your Canvas, the old drawings are still on the surface and that is probably one way to "update just a part" of the screen.
So, if you want to "update a part of the screen", just avoid calling Canvas.drawColor() method.

u can't erase a canvas. you'll have to draw a color on it each time before a frame.
Canvas.drawColor(Color.BLACK);
//draw frame
it takes a little practice but youll get the trick ecantually

I use path.reset() it working for me, clean all the screen.

Related

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.

Can we update the part of canvas without updating entire canvas?

I am extending the ImageView to display the images. The input stream for images is getting from socket along with their top left coordinates.
I am able to display the part of image,where as the remaining screen is white.My problem is total canvas is overridden with the current bitmap and the previous drawings are erased with white screen.
I searched for the solution,I come across to known the information about canvas is "Every pixel of canvas is drawn when canvas.drawBitmap(bitmap,top,left,paint) is called".
I need to update the only dirty part of image(canvas) without updating the entire canvas.
Please suggest me How to update the dirty part of screen(canvas) and previous drawings should not be erased.
Thanks & Regards
Mini.
You can make a canvas from what you already have instead creating a blank on and then draw on it. This is an example of how to achieve it.
yourImageView.setDrawingCacheEnabled(true);
Bitmap bm = yourImageView.getDrawingCache();
final Canvas canvas = new Canvas(bm);
Then you have a canvas, which contains whatever was previously in ImageView and you can update whatever part you want. For that I would recommend having a look at PorterDuff modes.

Draw a shape that tracks my finger

I know how to draw paths on a canvas and understand how to undo/redo. But now I want to draw shapes (lines, circles, rectangles) that dynamically resize depending on how I drag them - just like we have in MS Paint.
If I use "drawLine", the line is there permanently with no way of erasing it and redrawing it to my new finger location. Same with circle as I want the circle to constantly change width as I drag my finger. So the old one has to erased (keeping all the other paths on the bitmap intact) and the new one drawn in its place.
Been searching a lot for this, but haven't come across how t do it. Maybe I'm using the wrong keywords, but I don't know. Any pointers?
Each time you move the finger, call the underlying view's invalidate() function, it will trigger erasing the entire background
public void invalidate ()
Since: API Level 1
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
Then redraw your shape based on your finger's new position.
Managed to do it. I misunderstood the way the offscreen drawing thing worked. The idea is to write to the bitmap only after you have the shape you want - ie on "touch up". Till then, draw the shape using the "canvas" object in on Draw...

reseting the canvas bitmap doesn't work correctly

i try to paint an arrow png on canvas with a png bitmap behind it. so every time i rotate the arrow i have to reset the background bitmap of the canvas becouse otherwise i would see duplicates of the old arrows.
i reset the background with:
bMapLoad.eraseColor(0);
the problem is that sometimes it erases parts of the new arrow. sow that i sometimes only see a part of the arrow. i rotate it aber every 10-100 ms.
can someone help me?
i also tried:
bMapLoad=bMapcanvasBack.copy(bMapcanvasBack.getConfig(), true);
canvasLoad.setBitmap(bMapLoad);
this works fine but needs more memory. so is there a better way?
edit:
also
canvasLoad.drawColor(0, PorterDuff.Mode.CLEAR);
don't work
Try canvas.drawARGB(0,0,0,0) or, more concise canvas.drawColor(0) to clear it, then draw the bitmap again (canvas.drawBitmap(...))
The partial overdrawing may have a different reason though - synchronization between drawing and display. A common practice is to use double buffering. This means, you would draw on a offscreen canvas, and then exchange the underlying Bitmap with the visible canvas.
EDIT: some useful resources on double buffering with android:
An example here plus the book "beginning android games" also features a section on double buffering. The source code for the book can be downloaded here

Antialiasing and updating a path lead to thicker lines than expected

The problem is pretty complicated to explain but here goes:
I'm making a paint program that draws paths onto a canvas with textured background. Each stroke is stored as a path that updates as the user moves the stylus across the screen. When the path is updated I call drawpath on the canvas. The problem is that on each move event, the path is drawn over the existing line on the canvas, so the antialiasing on it darkens the existing line and make it appear thicker and jaggier than expected.
I had a solution where I store the older canvas (the one without the active path) and keep another transparent canvas on top of that. I would clear the top canvas and redraw the path on each move event, and then draw both canvases together. BUT that makes the program so slow that the paths look terrible - you can tell the drawing is lagging way behind the stylus movements.
Is there any way to make either A) drawing / clearing multiple canvases faster or B) make antialiasing not mess up on multiple redraws?
Figured out.
It was so simple I can't believe I got stuck on it.
The "canvas" used in onDraw() is automatically erased every time, so I just called canvas.drawPath() with the currently updating path in the onDraw() function, at no extra cost.

Categories

Resources