Pages

Monday, October 29, 2012

Draw line on finger touch

There are many application in Android you can use to draw something on screen. This is a simple application which will draw straight line on screen between touch you have started and the last point of your touch. 

This application will use Bitmap, Canvas, and Paint class.

Bitmap class covers some common techniques for processing and loading Bitmap objects in a way that keeps your user interface (UI) components responsive and avoids exceeding your application memory limit. 

Canvas class holds the DRAW calls. To draw something, you need four basic components: A bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Circle), and a paint (to describe the colours and styles for the drawing).

Paint class holds the style and colour information about how to draw geometries, text and bitmaps.
 
1. Design Screen: 

activity_touch_draw.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

An ImageView will be used as drawing board and your finger will work as pencil. A straight line will drawn from starting touch to ending point where user pull up finger. 

TouchDraw.java
package app.test;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class Test extends Activity implements OnTouchListener {
  ImageView imageView;
  Bitmap bitmap;
  Canvas canvas;
  Paint paint;
  float downx = 0, downy = 0, upx = 0, upy = 0;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    imageView = (ImageView) this.findViewById(R.id.ImageView);

    Display currentDisplay = getWindowManager().getDefaultDisplay();
    float dw = currentDisplay.getWidth();
    float dh = currentDisplay.getHeight();

    bitmap = Bitmap.createBitmap((int) dw, (int) dh,
        Bitmap.Config.ARGB_8888);
    canvas = new Canvas(bitmap);
    paint = new Paint();
    paint.setColor(Color.GREEN);
    imageView.setImageBitmap(bitmap);

    imageView.setOnTouchListener(this);
  }

  public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
      downx = event.getX();
      downy = event.getY();
      break;
    case MotionEvent.ACTION_MOVE:
      break;
    case MotionEvent.ACTION_UP:
      upx = event.getX();
      upy = event.getY();
      canvas.drawLine(downx, downy, upx, upy, paint);
      imageView.invalidate();
      break;
    case MotionEvent.ACTION_CANCEL:
      break;
    default:
      break;
    }
    return true;
  }
}

First of all you'll need to know what is width and height of your screen. You'll need Display class object to get detail about screen. Display class provides information about the display size and density.   


Display currentDisplay = getWindowManager().getDefaultDisplay();
float dw = currentDisplay.getWidth();
float dh = currentDisplay.getHeight();

currentDisplay object will provider display width and height.
bitmap object will of provided width and height.
canvas object will used to class draw functions. Your actual line will draw on canvas.
paint object will actually a line on the canvas.

Finally, user will draw on screen line by touching ImageView object. So, I have set OnTouchListener on ImageView object.

OnTouchListener is an interface definition for a callback to be invoked when a touch event is dispatched to the view.

onTouch method is called when a touch event is dispatched to a view. This allows a listeners to get chance to respond before the target view.
public boolean onTouch(View v, MotionEvent event)

  • is object of View class from where touch is dispatched.  
  • event is object of MotionEvent containing full information about event

int action = event.getAction();

getAction() return the kind of action being performed. During entire process of drawing a line on touch many actions will be called like.

  • ACTION_DOWN
  • ACTION_MOVE
  • ACTION_CANCEL
  • ACTION_UP

So, I need to draw a line starting from action called ACTION_DOWN up to the action ACTION_UP. I have taken starting X & Y co-ordinate where ACTION_DOWN action called and again I have retrieved ending X & Y co-ordinate when ACTION_UP action called. Finally, I have used drawLine() method of Canvas class to draw straight line.

39 comments:

  1. nice tutorial
    how to draw a line along finger

    ReplyDelete
    Replies
    1. Thanx, its very simple to draw line along finger.
      Instead of drawing a line in case statement MotionEvent.ACTION_UP event, you need to draw a very small circle in case statement MotionEvent.ACTION_MOVE event. That will draw a thick line along with your finger touch.

      Delete
    2. shouldn't it be like this?

      setContentView(R.layout.activity_touch_draw);

      Delete
  2. hi, Its a nice tutorial indeed. I'm having a problem that It doesnot draw line on proper mouse point OR touch point. How can i solve this problem?

    ReplyDelete
    Replies
    1. Is your line doesn't come on the place where you touch or its not coming just smoother.

      Delete
    2. My line doesn't come on the place where i touch :\

      Delete
    3. Check out your DRAWLINE() method friend or mail me your code.

      Delete
    4. Even my line doesn't come at the place where i touch. There is always some distance between them which is not constant

      Delete
    5. I am also having the same problem that Harshal and Killer talks about. Another problem is that the canvas does not cover the whole image area where as the imageview has been set to fill-parent(width,height).

      Delete
    6. Thanx i figured it out... :)

      Delete
    7. This comment has been removed by the author.

      Delete
  3. the line is not continuous, it is appearing like a dotted line how can I make it as a continuous line

    ReplyDelete
    Replies
    1. Hello friend. Its just happening because we normally move finger faster where as code can't execute at that speed. To solve your problem try to draw adjacent point of X & Y point. May this solve your problem.

      Delete
    2. Hi! I've done it in such way. First - add these variables
      float startX = 0;
      float startY = 0;
      float endX = 0;
      float endY = 0;

      Then, modify your switch like this

      switch (action) {
      case MotionEvent.ACTION_DOWN:
      startX=event.getX();
      startY=event.getY();
      break;
      case MotionEvent.ACTION_MOVE:
      endX = event.getX();
      endY = event.getY();
      canvas.drawLine(startX,startY,endX,endY, paint);
      imageView.invalidate();
      startX=endX;
      startY=endY;
      break;
      case MotionEvent.ACTION_UP:
      break;
      case MotionEvent.ACTION_CANCEL:
      break;
      default:
      break;
      }
      But I should mention, that I get not smoothy line, but it's solid.

      Delete
  4. Sharad, you still continue to respond to this post? I have a big question.
    thank you

    ReplyDelete
  5. I want draw straight line on image.Its look like height or width of image

    Example URL : https://itunes.apple.com/us/app/measured-measure.-store.-share./id488749934?mt=8

    you can see this..

    waiting for your replay..

    thanks in advance..

    ReplyDelete
    Replies
    1. Mayur, To make something look a like first you have to heading to Maths. I sorry but I am not aware about that much mathematical measurement. I can help you out in android queries but not in mathematical solutions.

      Delete
  6. My line doesn't come on the place where i touch :\ please post the changed or correct code

    ReplyDelete
    Replies
    1. I faced the same issue when I was drawing over the screenshot that I took.

      This occurs because the ImageView is bigger than the Bitmap of the screenshot (to maintain aspect ratio, the ImageView doesn't fill the width. You can confirm it by setting a colour background of the ImageView).

      So I basically did following the steps.

      1. add this to the onCreate():

      myImageView.getViewTreeObserver();
      vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
      public boolean onPreDraw() {
      mImageView.getViewTreeObserver().removeOnPreDrawListener(this);

      wrapWidthOfImageViewToBitmap();
      mScale = 1f * mOriginalBitmap.getHeight() / mImageView.getHeight();

      mAlteredBitmap = Bitmap.createBitmap(mOriginalBitmap.getWidth(), mOriginalBitmap.getHeight(), mOriginalBitmap.getConfig());

      mCanvas = new Canvas(mAlteredBitmap);
      mPaint = new Paint();
      mPaint.setColor(Color.GREEN);
      mPaint.setStrokeWidth(5);
      mMatrix = new Matrix();
      mCanvas.drawBitmap(mOriginalBitmap, mMatrix, mPaint);

      mImageView.setImageBitmap(mAlteredBitmap);

      return true;
      }
      });

      2. And added this helper method:

      private void wrapWidthOfImageViewToBitmap() {
      mImageView.getLayoutParams().width = mOriginalBitmap.getWidth() * mImageView.getHeight() / mOriginalBitmap.getHeight();
      }

      3. declared the following field:
      private float mScale;

      4. Then in the onTouch(), I replace:

      a. `event.getX()` with `event.getX() * mScale`, and
      b. `event.getY()` with `event.getY() * mScale`

      Now what I draw shows up where I want it to.

      Delete
  7. someone please reply me sooon....

    ReplyDelete
    Replies
    1. Did u solve the problem? I spent so much time on this....

      I found that creating bitmap on Layout change solves the problem.
      i.e. change the onCreate() to:

      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_touch_draw);

      /* set up Paint */
      paint = new Paint();
      paint.setColor(Color.BLACK);
      paint.setStrokeWidth((float) 3);

      /* Create bitmap */
      imageView = (ImageView) this.findViewById(R.id.imageView);
      imageView.setOnTouchListener(this);

      imageView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
      @Override
      public void onLayoutChange(View v, int left, int top, int right, int bottom,
      int oldLeft, int oldTop, int oldRight, int oldBottom) {
      // its possible that the layout is not complete in which case
      // we will get all zero values for the positions, so ignore the event
      if (left == 0 && top == 0 && right == 0 && bottom == 0) {
      return;
      }

      // Do what you need to do with the height/width since they are now set
      bitmap = Bitmap.createBitmap(right - left + 1, bottom - top + 1, Bitmap.Config.ARGB_8888);
      canvas = new Canvas(bitmap);
      Log.d("DrawLineOnFingerTouch", left + " " + top + " " + right + " " + bottom);
      paint = new Paint();
      paint.setColor(Color.BLACK);
      paint.setStrokeWidth((float) 3);
      imageView.setImageBitmap(bitmap);
      }
      });

      }


      Delete
  8. How can we draw continuous straight line(not ZigZag)

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Here's what you need. In order to plot the missing points you should query for the historical points (x,y) along with the other points. These are the points that form the intermediate skipped points. Search the internet on these lines and you should find some example implementing the same. Good Luck.

    ReplyDelete
  11. Working fine.
    But how to save as image?

    ReplyDelete
  12. Hi Could you please tell me how to draw arrow using finger?

    ReplyDelete
  13. Hi friends .. need one help how to draw over image please give idea how to implement..

    ReplyDelete
  14. i want this type of code finger touch feedback ontouch ImageView in androud

    ReplyDelete
  15. How to save as image?
    Thanks in advance

    ReplyDelete
  16. Hi I can draw the line But the image is not preview when use this code. I don't know what is the problem. Can you guide me

    ReplyDelete
  17. How would I do to record the gestures and then repeat them?

    ReplyDelete
  18. Amazing articles useful information.

    Web designing trends in 2020

    When we look into the trends, everything which is ruling today’s world was once a start up and slowly begun getting into. But Now they have literally transformed our lives on a tremendous note. To name a few, Facebook, WhatsApp, Twitter can be a promising proof for such a transformation and have a true impact on the digital world.

    we have offered to the advanced syllabus course web design and development for available join now.

    more details click the link now.

    https://www.webdschool.com/web-development-course-in-chennai.html

    ReplyDelete
  19. One of the knowledge stuffed blogs i've ever seen. It helps revamp existing technology and architecture, using constantly evolving strategies to drive improved market performance. reffer the given blog for more info Application Modernization Services or
    reach +18882075969 for more information

    ReplyDelete



  20. Buy Cow /Ox Gallstone Available On Stock Now @ (WhatsApp: +237673528224)

    DESCRIPTION
    -Full substance,
    -100% machine flayed
    -No ticks, no scratches, no humps
    -Size: 32 to 40 sq. ft.
    -Average size: 36 sq. ft.
    -Weight: 22kgs to 32kg
    -Average weight: 25kgs
    -Selection: 80% A/B, 20% C/D
    -Male 75% / Female 25%
    -1 x 40 container = 1700-2000 hides
    -Availability: 10 x 40 ft container
    - Impurity: No sand, No dust, No mud, No foreign object, no fats and no meat
    - Not available: No hair slip problem, No rotten Hides, No fats and meat on the Hides, No

    mule
    - No Holes, No Cuts, No Reheated,
    -Sand: non and clean from any other dust or mud.

    All Inquiries Below

    Email: infodocuments4@gmail.com
    WhatsApp: +237673528224


    Cow /Ox Gallstones

    Specifications

    Cow /Ox Gallstones for sale for (wholestone / brokenstone ratio is 80% / 20% )
    We are full time exporters of high quality natural ox gallstone.
    Our product obtained from disease free cattle.
    We can supply up to 10 Kg. monthly. Shipment prompt by air courier (DHL).

    Price depends on the ratio of wholestone / brokenstone.

    wholestone / brokenstone ratio is 80% / 20%
    wholestone / brokenstone ratio is 70%/30%
    wholestone / brokenstone ratio is 60%/40%

    Functions:

    To clear heat and release toxins.
    To eliminate endogenous wind and stop convulsions.
    to resolve phlegm and promote resuscitation.If you wish to try out what we
    have,then we will be so much so pleased to get your inquiry.


    ReplyDelete
  21. To utilize vilitra 60 tablets containing vardenafil, you can escape the issue like Erectile brokenness in an exceptionally brief time frame. If you have any desire to store this tablet, you ought to get this tablet far from dampness and daylight. You ought to accept it as endorsed by the specialist.
    vilitra 20
    vilitra 40

    ReplyDelete