Search code examples
androidcanvasimageviewdrawable

How do I draw an image from drawable onto an imageview with Canvas - Android


I have an activity which has an ImageView in it. What I want to do is be able to draw where the user touches that Imageview with an image from the drawable folder. I've read that the best way is to use Canvas, but I'm not sure where and how I integrate the onDraw method with the onTouchListener. This is what I have so far:

public class Main extends Activity
{
   @Override
   public void onCreate(Bundle savedInstanceState)
   {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      final TextView textView = (TextView)findViewById(R.id.textView);
      final ImageView image = (ImageView) findViewById(R.id.imageView2);

      //Bitmap
      Bitmap viewBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
      Canvas canvas = new Canvas(viewBitmap);
      image.draw(canvas);

      image.setOnTouchListener(new View.OnTouchListener()
      {
         @Override
         public boolean onTouch(View v, MotionEvent event)
         {
            textView.setText("Touch coordinates : " + String.valueOf(event.getX()) + "x" + String.valueOf(event.getY()));
            return false;
         }
      });
   }
}

So what I want to do is when the user touches the ImageView, an image will be drawn exactly where he touched it.


Solution

  • You're going to want to subclass ImageView in order to override its onDraw() method. By doing so, you can also to the custom touch handling in onTouchEvent() instead of attaching a listener. This is not a complete example, but something like the following:

    public class CustomImageView extends ImageView {
    
        private ArrayList<Point) mTouches;
        private Bitmap mMarker;
    
        //Java constructor
        public CustomImageView(Context context) {
            super(context);
            init();
        }
    
        //XML constructor
        public CustomImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        private void init() {
            mTouches = new ArrayList<Point>();
            mMarker = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_marker_image);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //Capture a reference to each touch for drawing
            if(event.getAction() == MotionEvent.ACTION_DOWN) {
                mTouches.add( new Point(event.getX(), event.getY()) );
                return true;
            }
    
            return super.onTouchEvent(event);
        }
    
        @Override
        protected void onDraw(Canvas c) {
            //Let the image be drawn first
            super.onDraw(c);
    
            //Draw your custom points here
            Paint paint = new Paint();            
            for(Point p : mTouches) {
                c.drawBitmap(mMarker, p.x, p.y, paint);
            }
        }
    
    }
    

    HTH!