• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Drawing a Line on a Canvas with Finger - Line not appearing where touched

Hi Everyone,

I am studying android programming in college - using Android Studio.

The app I am trying to create captures an image using an intent - then scales the image down and loads it as a bmp into an imageview. Once in the imageview, a canvas is created and the user should be allowed to draw lines on the image.

My lines are not appearing where the user is touching on the screen... heres my code:
Java:
package com.example.emmetdunner.measurements;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Path;
import android.media.Image;
import android.view.MotionEvent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.Telephony;
import android.support.v4.content.FileProvider;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Measurement extends Activity implements View.OnClickListener, View.OnTouchListener{
    //keep track of camera capture intent
    final int requestImageCapture = 1;
    Uri photoURI; //the Uri for the captured image 40
    ImageView mImageView;
    EditText mDialogInput;
    Context mContext;
    File photoFile;
    String mCurrentPhotoPath;
    Canvas canvas;
    Paint PaintLine;
    Paint PaintText;
    float downx = 0, downy = 0, upx = 0, upy = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_measurement);
        //retrieve a reference to the UI button
        Button captureBtn = (Button) findViewById(R.id.captureButton);
        //handle button clicks
        captureBtn.setOnClickListener(this);
        mImageView = (ImageView) findViewById(R.id.imageViewer);
    }

    public void onClick(View v) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
                Toast errorMessage = Toast.makeText(this, "Your droid does not support capturing images!", Toast.LENGTH_SHORT);
                errorMessage.show();
            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, requestImageCapture);
            }
        }
    }

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        //user is returning from capturing an image using the camera
        if (requestCode == requestImageCapture) {
            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
            String newString = mCurrentPhotoPath;
            // Get the dimensions of the bitmap
            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            bmOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(newString, bmOptions);
            int photoW = bmOptions.outWidth;
            int photoH = bmOptions.outHeight;
            // Get the dimensions of the View
            int targetW = mImageView.getWidth();
            int targetH = mImageView.getHeight();
            // Determine how much to scale down the image
            int scaleFactor = Math.min(photoW / targetW, photoH / targetH);
            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inSampleSize = scaleFactor;
            bmOptions.inPurgeable = true;
            bmOptions.inMutable = true;
            bmOptions.inJustDecodeBounds = false;
            Bitmap bmp = BitmapFactory.decodeFile(newString, bmOptions); //Load with scaling
            canvas = new Canvas(bmp);
            PaintLine = new Paint();
            PaintLine.setColor(Color.MAGENTA);
            PaintLine.setStrokeWidth(6f);
            PaintLine.setStyle(Paint.Style.STROKE);
            PaintText = new Paint();
            PaintText.setColor(Color.MAGENTA);
            PaintText.setStrokeWidth(2f);
            PaintText.setStyle(Paint.Style.STROKE);
            mImageView.setImageBitmap(bmp);
            mImageView.setOnTouchListener(this);
        }
    }
}

    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );
        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }

    public boolean onTouch(View view, MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                downx = event.getX();
                downy = event.getY();
                Toast cord = Toast.makeText(this, Double.toString(downx) + " " + Double.toString(downy), Toast.LENGTH_SHORT);
                cord.show();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                upx = event.getX();
                upy = event.getY();
                showDialog();
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
            default:
                break;
        }
        return true;
    }

    private void showDialog(){
                canvas.drawLine(downx, downy, upx, upy, PaintLine);
                canvas.drawText("1", (downx + upx) / 2, ((downy + 20) + (upy + 20)) / 2, PaintText);
                mImageView.invalidate();
    }
   
}

I presume it is something to do when the coordinates are retrieved using event.getX() and event.getY() - this seems to get the coordinates of the entire view rather then just the imageview.

Any help would be really appreciated!
 
To verify your coordinates, run the app in debug mode, and set a breakpoint in the showDialog() method. Look at the values of variables downx, downy etc.
 
To verify your coordinates, run the app in debug mode, and set a breakpoint in the showDialog() method. Look at the values of variables downx, downy etc.
Hi,

Thanks for your help. The coordinates appear to be from the view rather then the imageview itself. The mImageView.getLeft() method returns 7.0 and the mImageView.getHeight() method returns 199.0. I was thinking of working out some sort of scale factor.

Clicking in the approx. middle of the mImageView returns coordinates displayed in the toast message shown in the screenshot below:
 

Attachments

  • Screenshot_1512421136.png
    Screenshot_1512421136.png
    156.1 KB · Views: 86
Back
Top Bottom