How to dynamically draw bitmaps to a Canvas in Android? - android

Here is the scenario of the issue .
A custom view which is a canvas on which I need to draw .
2 buttons beneath it ,lets call them A and B
When A is clicked -> Image A is drawn to the above canvas .
When B is clicked -> Image B is drawn to the above canvas .
The issue demands that the previously drawn image on canvas must be preserved . That is if you click button A followed by button B then the canvas must contain two images . So the previous images need to be preserved.
Problem : How do you achieve this ?
Possible solution 1 : Create an ArrayList and keep adding images to this arrayList . Pass the updated arrayList to canvas onDraw method and redraw every single image for every button click .
Possible solution 2 : There has to be some method to preserve the state of the canvas so that on each button click you draw on canvas's last preserved state and draw only the new image .
Further Requirements : The Images drawn to canvas could be dragged so need to keep track of updated positions .
I am at an impasse and couldn't find a good tutorial or a book tackling such requirement , any help is appreciated .

You can create the Bitmap, and draw what you want on it.
Bitmap mBitmap;
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed) {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
mBitmap = Bitmap.createBitmap(right - left, bottom - top, Bitmap.Config.ARGB_8888);
redrawAllYourStuffTo(mBitmap);
}
}
when button is pressed, you can draw directly to bitmap, like this:
Canvas canvas = new Canvas(mBitmap);
canvas. ... // draw operations.
// after the bitmap canvas drawing finished, call
invalidate();
in onDraw just paint your bitmap
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, null);
}

Related

Xamarin Android: How to draw on top of Canvas

I am writing a custom renderer for Xamarin.Forms. I am overriding the class ImageRenderer to do some tweaks to the image.
However, I want to overlay some parts of the image with circles, so I override the method void OnDraw(Canvas canvas).
Then I modify the Canvas a bit by drawing some circles:
protected override void OnDraw(Canvas canvas)
{
var paint = new Paint
{
Color = Color.Red
};
paint.SetStyle(Paint.Style.Fill);
foreach (var mapObject in _control.PointSource)
{
canvas.DrawCircle(mapObject.Location.X, mapObject.Location.Y, 100 / _scaleFactor, paint);
}
base.OnDraw(canvas);
}
However, everything is drawn on the background. The actual image is always on top. How can one draw circles on top of the image?
https://developer.xamarin.com/api/member/Android.Views.View.OnDraw/
In the docs they say the following:
the canvas on which the background will be drawn
So the current behaviour was expected.
I managed to fix it by moving the circle logic to the function: void Draw(Canvas canvas).

Draw second bitmap on the first bitmap by method onDraw in Android studio

I created a customView class which exteds from View. In the method onDraw, I made a canvas and put the bitmap there, then I draw lines and circles on it. I called it in an other class in order to draw it.
Now I need to draw other bitmap on the First Bitmap. When I make another canvas in onDraw and draw the new bitmap there, the application stops working.
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Canvas singleUseCanvas = new Canvas();//Canvas in order draw second bitmap
canvas.drawBitmap(firstBitmap, 0, 0, new Paint());
singleUseCanvas.drawBitmap(roomIconBitmap,100,100,iconPaint); // Second bitmap
}
My question is: how can I draw a bitmap on an other bitmap by onDraw method?
I hope that I could ask my question well. Thank you in advance!

canvas not redrawing correctly

I am writing a simple view that will show a dot, after some action, show the next dot. The dots are on a vertical strip. so I create a function that'll clear the strip. then draw a circle at the position where I want the dot. the code segment is as followed.
private void clear_strip(){
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
m_canvas.drawRect( 0, 0,width/8, height, paint);
paint.setColor(Color.GREEN);
}
private void set_dot(){
clear_strip();
m_canvas.drawCircle(width/10, (int) (font_height*(scoreboard.current_batter_position()+0.5))/1, font_height/4, paint);
}
#Override
protected void onDraw(Canvas canvas) {
set_dot();
canvas.drawBitmap(m_bitmap, 0, 0, paint);
}
but one of the dot is just not updating. It'll keep the old dot, skip that dot, then move to the next dot. I tried to print out the position to logcat right before the drawCircle call, and the position is right, it's just not drawing (and not clearing as well)....please advise.
You get a canvas to draw into passed into your onDraw method. But the point drawing code uses the canvas m_canvas. Pass the canvas as a parameter to your dot drawing code to fix that.

Canvas and drawing image in layout

I have a code where I draw image:
class Panel extends View {
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.calvin_logo_small);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_scratch, x-point, y-point, null);
}
}
How can I draw this image in my activity, but I don't want to change may layout. I have layout: setContentView(R.layout.main); This is possible to draw in this lauout with canvas? I have this activity and this layout have a lot of components. I only want image in place where I click with canvas. This is idea. I start application where start activity with my setContentView(R.layout.main);. After that I click on the screen and canvas draw picture in place where I clicked. This is possible to do?
Your code should work. Just override the onTouchEvent() for the view, store the co-ordinates of the touch event in field variables and invalidate() the view so that onDraw() would be called. Use the co-ordinates in onDraw() to render the image as you've already done.
To improve performance, you can cache the bitmap if it's not going to change.

How I can draw an existent Canvas on another Canvas?

Now I need to draw a new Canvas in an existent Canvas (the parent Canvas), like Bitmap's works.
The logic is this:
Each Sprite can have others Sprite nodes (LinkedList<Sprite> nodes);
If don't have nodes (nodes = null) then, will draw the (Bitmap) Sprite.image directly to parent canvas, received on update method, like (currently working):
public void update(Canvas canvas){
if(this.nodes == null){
canvas.drawBitmap(this.image, ...);
}
...
}
If it have nodes, I need create a new Canvas, draw nodes bitmap on this, and draw the new Canvas on parent Canvas. This don't works, but the idea is like this:
public void update(Canvas canvas){
...
else { // this.nodes != null
Canvas newCanvas = new Canvas();
for(Sprite node: this.nodes){
node.update(newCanvas);
}
// Canvas working like Bitmap! (?)
canvas.drawCanvas(newCanvas, this.x, this.y, this.paint);
}
}
Real example usage: well, I have a Sprite called CarSprite. The CarSprite have a private class called WheelSprite extends Sprite. The CarSprite implements two nodes (two dimensional example) of WheelSprite, that will be positioned in the CarSprite to seems the whell of car. So far, no problem.
But if CarSprite is affected by a devil one object in the level, this will be turn transparent. I will do, for instance, objectOfCarSprite.paint.setAlpha(127);. The problem is, if I do it (currently working mode), only the car bitmap will turn transparent, but not the well, because it is drawed directly to global Canvas object.
This part does not influence much: currently, I'm getting the parent (of parentN...) Paint object alpha, and with some math, I get a transparent solution to wheel that works almost as well I need, but if, for instance, the WheelSprite object is over car bitmap, is possible to see the ground of car, like picture.
Exists a better way to do like I want, or only like work currently?
I do it. But is very slow, but works fine.
final Bitmap split = Bitmap.createBitmap(GameActivity.screenWidth,
GameActivity.screenHeight,
Bitmap.Config.ARGB_8888);
final Canvas subCanvas = new Canvas(split);
for(final Sprite sprite: this.nodes) {
sprite.update(subCanvas);
}
canvas.drawBitmap(split, this.x, this.y, this.paint);
First we need have a Canvas object (here just canvas);
After, we need make a Bitmap where we will draw. This need get a width and height from current canvas. I used a shortcut on this case;
Next, we need make a new Canvas, it will be passed to Sprite.nodes;
After all, we need draw the bitmap on global canvas;
Note: this works very well, but affect to much the speed.

Categories

Resources