Application gets too slow while drawing two bitmaps on a Canvas ! - android

I have two bitmap overlapped .The top bitmap is transparent and when user touch to screen i copy pixels from another bitmap to top bitmap.My goal is to give to users the feeling of erasing image with touching to see another image.However it is not working properly especially when user drags his finger too fast on the screen.I made a few tests and i beleive drawing bitmaps to the canvas every time cause the lag but i don't know how to fix it.

It looks like a Canvas or Bitmap isn't redrawn until you wipe it yourself. That means you just have change the alpha value of the pixels in the top Canvas/bitmap/thingy that are being "painted" rather than redrawing the entire canvas for every update.

Related

Setting a listener on bitmap in a canvas?

I have a view in which I have placed a canvas and on that canvas I draw a few bitmaps dynamically (based on some calculation). The user needs to be able to touch a bitmap and get a response (ie. a dialog should appear). I understand that bitmap is a representation of an image and that it cannot hold a listener on its own.
Is there a smarter way of doing this other than placing a listener on the entire view (which fills the whole screen) and then checking if the coordinates of the touch event match the area covered any of my small and scattered bitmaps?
I will write this so that the question doesn't stay unanswered. The answer is "No." You have to do it the hard way, mentioned above.

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.

Dirty rects on a Canvas received from a SurfaceHolder's lockCanvas()

Is that possible? Because I need to draw a photo-background with moving objects on top of it, in atleast 35 fps. It must take alot of resources to redraw that whole background every frame, even for a short time? (live wallpaper)
I tried to redraw the background only at each moving object's Rect, but that only makes those parts of the screen flickering.
Ok it seems there is no big gain anyways in doing these opmimizations.
The flicker is ofcourse because of double-buffering, there are Two buffers to erase, therefore the flickering.

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