Save canvas drawings on bitmap? - android

I'm using a SurfaceView and canvas. Over time The canvas draws the same bitmap image but at different position. So every time the position of the bitmap moves, any drawings on the bitmap has to be be moved as well. So is there a way to just have the drawings on the bitmap image stay so that when the image moves(when canvas redraws the bitmap at a different location on screen), any drawings on the image moves with it as well?

You can setup a Bitmap to be the backing buffer for your canvas so that drawing to the canvas is, effective, drawing to that Bitmap. This way you can keep it around and do whatever you want with it.

Related

Why does drawing a shape to a bitmap reduce quality?

Why does drawing a shape to a bitmap cause the shape to be blurry versus drawing the shape straight to the canvas?
Bitmap is a rasterized computer image, consisting of points (pixels).
The Canvas class holds the "draw" calls.
A shape is an abstract definition of shape (vector-like).
drawing the shape straight to the canvas
That's not accurate, maybe you mean straight to the screen of device, which is Bitmap too.
To use Canvas for drawing, you need the canvas to host the calls, some bitmap as target, and some drawing primitive (shape is one), and Paint (contains information how to paint the drawing primitive).
Once you draw some shape into the target bitmap, it will be aliased to the pixels of target bitmap. Ie. an circle will turn into some approximation created by rectangular pixels of target bitmap.
What you probably see in your particular case is, that your Bitmap has lower resolution than screen, and when you draw that low-res bitmap to the target screen bitmap, it is upscaled by some filter which makes the upscaled picture a bit blurry to avoid big rectangular pixelation (or it may be also other way, downscaling hi-res bitmap, which contains too sharp/thin contours, which will be aliased second time when downscaled, and even with anti-aliasing filtering it will get blurred a bit). Or maybe you use some paint with settings causing blur (unlikely, can't think of creating one by accident, you would knew).
If you will use for both targets Bitmap of identical density (resolution of single pixel), and the same paint method, then the result will be same, and also drawing the shape from bitmap to bitmap as long as you will use whole pixel coordinates/size, and no filtering, again the result will be same as drawing directly to screen bitmap.
So start first by checking the size of your bitmap vs screen bitmap, and then check paint settings and additional canvas arguments to draw the bitmap, whether you don't upscale/downscale it with some kind of filtering.

Save image on Canvas to bitmap

How can I save the image on a canvas to bitmap?
There are several related posts, but I didn't find the one works for me. To make it clear, here is my problem
What's on my canvas:
An bitmap image which was drawn to the canvas using canvas.drawBitmap(oldBitmap, x, y, null);
Some paths drawn overlay to this image on the same canvas using canvas.drawPath.
Both the image and the paths are draw on a customized SurfaceView. And both they are draw to the canvas in the onDraw function. Or more specific, the implementation is in the following link:
Android: custom draw on an given image (with SurfaceView)
Now I need to save the image on canvas (the oldBitmap and paths I drew) to a newBitmap. Could someone tell me how to do that?

Android: drawing on large bitmap, 2 layers, best way?

im working on an app, that displays large(around 2000x2000px) bitmap in imageview. This image has to be that large since user can pinch to zoom it in order to see some details. App has to be able to draw circles on that image, and also to display image alone, without circles on it. I was using 2 layers but the problem is memory since 2k x 2k px is around 16mb of memory, and creating another bitmap(another 16mb), just to draw a few circles, is pointless in my opinion. Is there any way, that you can draw simple primitives on image, and also be able to display it without primitives(circles in my case)?
Maybe somehow to store only modified pixels or sth?
Thanks!
You don't need to make another 2000x2000 Bitmap to draw those circles on. Just 'prerender' a circle, and then choose where you draw it.
I'm working under the assumption that you're drawing your 'big' image on a Canvas, since you have zooming features etc.
If you're not, you'll need to override your SurfaceView's onDraw(Canvas canvas) method so that you can access the SurfaceView Canvas. I won't go into depth about that part since again I'm assuming you have it, but if not the implementation of that function would look like this:
//Overriding SurfaceView onDraw(Canvas canvas)
#Override
protected void onDraw(Canvas surfaceCanvas) {
if(canvas == null) return; //No Canvas? No point in drawing then.
surfaceCanvas.drawColor(Color.BLACK);
//Draw your 'big' image on the SurfaceView Canvas
insertYourBigImageDrawingFunctionHere(surfaceCanvas);
//Now draw your circles at their correct positions...
insertCircleDrawingFunctionHere(surfaceCanvas);
}
Now that you have access to the SurfaceView Canvas, you can choose precisely how things are drawn on it. Like circles for example...
I want to draw your attention to the multiple Canvas' being used below (surfaceCanvas vs. circleCanvas). I once thought that Canvas was a kind-of 'one Canvas for the whole app/activity' implementation, but it isn't. You are free to create Canvas' as you please. It is merely an instance of a tool to draw onto Bitmaps. This was a HUGE revelation for me, and gave me much more robust control over how Bitmaps are composed.
public void myCircleDrawingFunction(Canvas surfaceCanvas){
//Make a new Bitmap for your circle
Bitmap.Config conf = Bitmap.Config.ARGB_4444;
tinyCircleBMP = Bitmap.createBitmap(10,10, conf);
//Make a new canvas using that Bitmap as the source...
Canvas circleCanvas = new Canvas(cacheBmp);
//Now, perform your drawing on the `Canvas`...
Paint p = new Paint();
circleCanvas.drawCircle(5, 5, 5, p);
//Now the `Bitmap` has a circle on it, draw the `Bitmap` on the `SufaceView Canvas`
surfaceCanvas.drawBitmap(tinyCircleBMP, 10, 10, p);
//Replace the '10's in the above function with relevant coordinates.
}
Now obviously, your circles will zoom/pan differently to your 'big' image, since they are no longer being drawn at the same size/position of the 'big' image. You will need to consider how to translate the positions of each circle taking into account the current scale and position of the 'big' image.
For example, if your image is zoomed in to 200%, and a circle is supposed to appear 100px from the left of the big image, then you should multiply the pixel values to take into account the zoom, like this
(PsuedoCode):
drawCircleAtX = Bitmap.left * BitmapZoomFactor
If you are using the canvas API (if not I would suggest to)? if so you are just draw your image on the canvas and then the primitive shapes on top of the same canvas before display. This way you just keep a reference of the circles position in some basic data types and scale them as the user moves around and zooms, so you know where to draw them each frame.

Android undo circle drawn on bitmap

I have an ImageView loaded with bitmap. When user touches on the bitmap, I draw a circle using canvas at the touched position on the bitmap. Now, I need to undo the drawn circle. Everywhere, I find snippets to undo paths drawn and not a circle directly. Does anyone have a solution to undo the previously drawn circle ?
There are two ways to erase the previous drawings
If you want to continue with the bitmap just assign null to the bitmap object when you want to remove the drawings in the bitmap. When you assign null the entire bitmap will cleared.
bitmapobj = null;
Another method is using the canvas for drawing, then each time you call the invalidate() the entire canvas will redraw and erase the previous drawing.
(Invalidate() is the default method that call the onDraw() which draws the shapes).

Android save canvas screen as bitmap

Is there a way to do it? I d like to save the canvas screen as a Bitmap object, and then draw it again, to the screen.
You can construct a Canvas passing in a Bitmap onto which the canvas will draw. See http://developer.android.com/reference/android/graphics/Canvas.html#Canvas(android.graphics.Bitmap)
You need to construct a Bitmap appropriately sized to the view into which you want to draw.
Just guessing here, but if you are doing this because you want to draw off screen then draw the bitmap on all at once you might also look at SurfaceHolder/SurfaceView.

Categories

Resources