Draw From Old Canvas - Android - java

I'm making an App that needs to be able to draw new graphics on top of the last set.
This is my current onDraw() method -
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
if(points.size() > 0) {
//do some stuff here - this is all working ok
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
}
}
Basically, I need to draw the new graphics as a layer on top of the last, so what I'm looking for is a way to carry the image of the last canvas to the current.
I have tried to figure it out myself using the canvas.setBitmap() method but it acts very funny.
Any help appreciated :)
P.S if it's needed, the the class extends SurfaceView and implements SurfaceHolder.Callback
Edit: This is what I have tried in the onDraw() method but it just force closes
if(bitmap != null) {
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.setBitmap(bitmap);
}

Found the answer myself :)
#Override
protected void onDraw(Canvas c) {
if(bitmap != null && canvas != null) {
canvas.drawLine(p1.x, p1.y, p2.x, p2.y, linePaint);
c.drawBitmap(bitmap, 0, 0, linePaint);
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
}
Works exactly as intended, it creates the effect of drawing on top of the old canvas continuously

You will have to store the previous image persistently onto a ArrayList, and during ondraw, loop through the ArrayList to redraw all items.
something like this:
for (Graphic graphic : _graphics) {
bitmap = graphic.getBitmap();
coords = graphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}

Related

Why my canvas is drawing nothing instead of a point?

I'm new to Android and I want to draw points on top of my view using a canvas, but when my OnDrawListener is hit, nothing is drawn on my view and I can't figure out why.
new OnDrawListener() {
#Override
public void onLayerDrawn(Canvas canvas, float pageWidth, float pageHeight, int displayedPage) {
canvas.drawPoint(pageHeight /2, pageHeight /2, paint);
view.draw(canvas);
}
}
Here's how I setup my paint :
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(3);
Thank you.
UPDATE :
Here you can find my full class :
https://pastebin.com/ehB5NamS

Android: How to draw over downloaded bitmap and then populate it to ImageView?

My application is downloading a bitmap which is later populated into custom ImageView. However I want this bitmap to be updated before it is actually drawn on a canvas (I want to add some points over it). However as the result I see only populated bitmap without changes I made. Can anyone help?
Here is my onDraw method. "bitmap" object is set via setImageBitmap received from AsyncTask in onPostExecute() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (bitmap != null) {
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int padding = (width - bitmap.getWidth()) / 2;
canvas.drawBitmap(bitmap, padding, 0, null);
paint.setColor(Color.RED);
paint.setStrokeWidth(5f);
for (Face face : getPhotoObject().getFaces()) {
canvas.drawPoint(face.getLeftEye().x, face.getLeftEye().y, paint);
canvas.drawPoint(face.getRightEye().x, face.getRightEye().y, paint);
}
}
}
You can create a canvas with a bitmap at any time:
Canvas canvas = new Canvas(myBitmap);
// draw code
// the resulting bitmap will be edited.
Hope this helps

How to access canvas width outside of the onDraw method Android

I have the following code:
Bitmap right1;
public TicTacToe(Context context) {
super(context);
right1 = BitmapFactory.decodeResource(getResources(), R.drawable.plus);
int width = right1.getWidth();
int height = right1.getHeight();
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth()/3, canvas.getWidth()/3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth()/3)), 0, null);
invalidate();
}
I want to rescale the bitmap that is called "right1" based off of what the width of the canvas is. I succeeded in doing this, but the line of code that does this is the third line under the onDraw method. The problem with that line of code is that it will constantly loop when I would like to only run it once. Idealy I would like to put that line of code within the TicTacToe method, but I am unsure how to initialize the canvas within the TicTacToe method so that I can get the canvas width.
You don't need to do this stuff inside constructor just add condition in onDraw() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
if(right1==null){
right1 = Bitmap.createScaledBitmap(right1, canvas.getWidth() / 3, canvas.getWidth() / 3, false);
canvas.drawBitmap(right1, (canvas.getWidth() - (canvas.getWidth() / 3)), 0, null);
invalidate();
}
}

Android Canvas weird shifting

I have a problem I was trying to solve for almost 2 days. (It ended up by switching to OpenGL :D)
Anyway... I have Canvas and I am trying to do a simple snake game. Just for this problem imagine our snake is made up from 5x5 pixels rectangles, he is leaving the trail (no clearing) and moving to the right from 0, 50 position... here is the code:
public class Snake extends AnimationWallpaper {
#Override
public Engine onCreateEngine() {
return new SnakeEngine();
}
class SnakeEngine extends AnimationEngine {
int i = 0;
Paint paint = new Paint();
#Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// By default we don't get touch events, so enable them.
setTouchEventsEnabled(true);
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
}
#Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep, int xPixelOffset,
int yPixelOffset) {
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep,
xPixelOffset, yPixelOffset);
}
#Override
public Bundle onCommand(String action, int x, int y, int z,
Bundle extras, boolean resultRequested) {
if ("android.wallpaper.tap".equals(action)) {
}
return super.onCommand(action, x, y, z, extras, resultRequested);
}
#Override
protected void drawFrame() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
draw(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
}
void draw(Canvas c) {
//c.save();
//c.drawColor(0xff000000);
paint.setAntiAlias(true);
// paint the fill
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
c.drawRect(i*5, 50, (i+1)*5, 55, paint);
//c.restore();
}
#Override
protected void iteration() {
i++;
super.iteration();
}
}
}
And here is output:
And that is not all, when it draws its kinda shifting... meaning what you see is shifted to the right side so it doesnt actualy stand in the same place...
If you have any idea why is it behave like that, please tell me!
In canvas, there's a reusability functionality which practically just add new drawings to whatever is in the canvas, hence if you are drawing 1 square at the time, the next time you will have whatever u had before +1, if you don't want that, and you want to fully manipulate every single draw from scratch, just add this line of code before to start drawing
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
It will clear anything you had in the previous state of the canvas, and you can start again drawing whatever you want...
Hope It Helps!
Regards!

Draw in bitmap using canvas doesn't work in android view

I'm trying to use onDraw method and canvas to draw some items in a bitmap and cache it to draw it again and don't call onDraw again
This is part of my code :
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCacheDrawing == null) {
mCacheDrawing = Bitmap.createBitmap(mScrollWidth, mScrollHeight, Config.RGB_565);
canvas.setBitmap(mCacheDrawing);
for (int i = 0; i < mIcons.size(); i++) {
prepareItem(canvas, paint, mIcons.get(i));
}
canvas.save();
} else {
canvas.setBitmap(mCacheDrawing);
}
}
The code is not working and show me an empty screen, can any one help me please?
EDIT : I have found the following post and it help me to solve the problem >> https://groups.google.com/forum/#!topic/android-beginners/6pO8SJN3CTY
and my working code now is following :
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mCacheDrawing == null) {
mCacheDrawing = Bitmap.createBitmap(mScrollWidth, mScrollHeight, Config.RGB_565);
mCanvas = new Canvas(mCacheDrawing);
for (int i = 0; i < mIcons.size(); i++) {
prepareItem(mCanvas, paint, mIcons.get(i));
}
}
canvas.drawBitmap(mCacheDrawing,new Rect (0,0, mScrollWidth, mScrollHeight), new Rect (0,0, mScrollWidth, mScrollHeight), paint);
}
Well i can't figure out functionality of your code as its a snippet from a section, But what I can figures out is the reason. quick check
If you trying to draw bitmaps from a view, make sure drawing cache is enabled/
canvas.drawBitmap , this is the API for drawing a Bitmap over a canvas and not setBitmap
you can use save and restore method of canvas accordingly.

Categories

Resources