1

I have tried so many methods but still my code refuses to simply draw a line on the canvas. Each of the attempts I have commented out either crash the program or won't display the line. I am really struggling to get my head around how to do this, I keep getting different advice on using threads or onDraw or whatever, but none seem to work.

My overall objective is to display a bitmap image on the screen, and draw lines on top of it. I then wish to use canvas.tranlate to make the entire image (the bitmap along with the lines on top of it) pan-able. (I have already implemented the functionality to pan the image successfully.)

public class Main extends Activity implements OnTouchListener {
CanvasView myCanvas;
Canvas canvas;
Bitmap bmp;
float fingerPosX = 0;
float fingerPosY = 0;
float preFingerPosX = 0;
float preFingerPosY = 0;
float bmpX = 0;
float bmpY = 0;
float dx = 0;
float dy = 0;
Paint paint;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    bmp = BitmapFactory.decodeResource(getResources(), R.drawable.gmit2013mod);
    canvas = new Canvas();
    myCanvas = new CanvasView(this);
    myCanvas.setOnTouchListener(this);
    setContentView(myCanvas);

}

@Override
public void onPause() {
    super.onPause();
    myCanvas.pause();
}

@Override
public void onResume() {
    super.onResume();
    myCanvas.resume();
}

public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    if(action == event.ACTION_DOWN) {       //when touch is received get finger position
        preFingerPosX = event.getX();   
        preFingerPosY = event.getY();
    }

    if(action == event.ACTION_UP) {         //when touch is released get finger position
        fingerPosX = event.getX();
        fingerPosY = event.getY();
        dx = fingerPosX - preFingerPosX;    //subtract previous finger position from current
        dy = fingerPosY - preFingerPosY;
        bmpX += dx;                         //apply difference to image
        bmpY += dy;
    }
    //CanvasView.updateMap();
    //invalidate();

    return true;
}

//CanvasView Class
public class CanvasView extends SurfaceView implements Runnable{ //implements Runnable
    SurfaceHolder surfaceHolder;
    Thread myThread = null;
    boolean isRunning = false;

    public CanvasView(Context context) {
        super(context);
        surfaceHolder = getHolder();
    } 

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    //  canvas.drawBitmap(bmp, 0, 0, null);
        //canvas = surfaceHolder.lockCanvas();
        canvas.drawLine(10, 10, 30, 30, paint);
        //surfaceHolder.unlockCanvasAndPost(canvas);
    }

    public void pause() {
        isRunning = false;
        while(true) {
            try {
                myThread.join();
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            break;
        }
        myThread = null;
    }

    public void resume() {
        isRunning = true;
        myThread = new Thread(this);
        myThread.start();
    }

    public void run() {
        while(isRunning) {
            //init(); //crashes when code here
            if(!surfaceHolder.getSurface().isValid()) {
                continue;
            }
            invalidate();
            //init();
            //canvas.translate(bmpX, bmpY);
            updateMap();
            //invalidate();
        }
    }

    //  canvas = surfaceHolder.lockCanvas();
    //  canvas.drawRGB(255, 255, 255);
    //  canvas.drawBitmap(bmp, 0-(bmp.getWidth()/2), 0-(bmp.getHeight()/2), null);
    //  surfaceHolder.unlockCanvasAndPost(canvas);
    }

    public void updateMap() {
        runOnUiThread(new Runnable () {

            public void run() {
                // TODO Auto-generated method stub
                //canvas = surfaceHolder.lockCanvas();
                //canvas.drawRGB(255, 255, 255);
                //canvas.drawBitmap(bmp, bmpX-(bmp.getWidth()/2), bmpY-(bmp.getHeight()/2), null);
                //paint.setColor(Color.RED);
                //canvas.drawLine(10, 10, 30, 30, paint);   //it seems this must b in ondraw. try canvas(bmp) again, mite have some affect with different bmp
                //invalidate();
                //surfaceHolder.unlockCanvasAndPost(canvas);

            }

        });
    }
}

Here is my code, if you can offer me any solution or some example of this already working online I would be grateful because I am running out of time on this project! Thanks

UPDATE: I added the following lines of code to the onCreate method:

Drawable drawBmp = new BitmapDrawable(bmp);
drawBmp.draw(canvas);
logicalfox
  • 83
  • 2
  • 13
  • Take a look at this link....[this][1] [1]: http://stackoverflow.com/questions/14427665/android-drawing-app-line-cannot-be-drawn-on-a-bitmap-loaded-from-gallery – AndiM Apr 17 '13 at 11:22

2 Answers2

1

You need to create the Bitmap as a Drawble object and then draw on that bitmap not on to the canvas it self.

So basically you create an object of BitmapDrawable with the help of Bitmap object that you have created with the help of BitmapFactory option. You will have to use the draw(Canvas c) method of this Drawable class to draw on the bitmap.

http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html

user_CC
  • 4,686
  • 3
  • 20
  • 15
  • sorry i didnt mean to post that bit of code on its own, I pressed enter by accident! i meant to say i added that line along with this one: drawBmp.draw(canvas); is this what u were refering to? – logicalfox Apr 17 '13 at 13:28
  • i updated the question user_CC. it doesn't crash the program now but screen stays black. do i have to call something to make all that draw to the canvas or? – logicalfox Apr 17 '13 at 14:11
  • is the bitmap coming up? also you need to draw on the canvas before calling the drawCanvas. – user_CC Apr 17 '13 at 14:56
  • no the bitmap is not appearing, just a black screen, but no force close either. yeah I have since tried to draw a line on the canvas using canvas.drawLine in my runOnUiThread. but it gave the same result. I dont think im calling this drawCanvas u just mentioned? – logicalfox Apr 17 '13 at 15:14
  • you havent drawn the bitmap on your MyCanvas View...where are you setting the bitmap on the MyCanvas? – user_CC Apr 17 '13 at 16:17
  • not quite sure what you mean by that, so I assume I haven't done it right. Do you mean `canvas = new Canvas();`? I had tried to make that `canvas = new Canvas(bmp);` in order to create a canvas from that bitmap, but it didn't work last time I tried it, that was how I thought it should be drawn – logicalfox Apr 17 '13 at 16:22
  • ok lets try this step by step...Firstly you need to use the BitmapDrawable object and then display it on the canvas...once you have done that then you will be able to draw on it... – user_CC Apr 18 '13 at 14:27
  • ok. what do you mean by "_use_ the BitmapDrawable object"? Drawable drawBmp = new BitmapDrawable(bmp); drawBmp.draw(canvas); does these 2 lines not create the object, and display it on the canvas? or is there more code I need to do what you are saying? – logicalfox Apr 18 '13 at 20:08
  • in your canvasview class in onDraw() method can you do canvas.setBitmap(bitmap) and then see if it comes up on background and then do the drawing via canvas.draw methods – user_CC Apr 22 '13 at 11:52
0

I needed to add paint = new Paint() in onCreate. Paint object was null so that's why it wouldn't draw. Took me weeks and a ridiculous amount of pestering just to spot that! I'm going on vacation...

If anybody plans on making a project like this I intend to make some youtube video tutorials in the near future to help anyone from falling into the same stupid pitfalls that I did!

Many thanks to user_CC too for all his time and help on this question!

logicalfox
  • 83
  • 2
  • 13