用手指在自定义imageview上绘图

最后发布: 2019-12-03 10:23:35


问题

我正在创建一个将图像加载到自定义imageview的应用程序。 这个自定义的imageview允许用户用手指在图像上绘制。 图像将通过毕加索加载到imageview中。 一切正常,但是我正在使用photoview进行缩放,但是当放大图像上的绘制线时,会随着缩放而缩放。 有什么办法可以做到这一点?

未应用缩放: 在此处输入图片说明

应用缩放: 在此处输入图片说明

如您所见,红色圆圈不随图像缩放,我希望它与图像有某种联系。

这是处理所有工程图的自定义图像视图:

public class PaintImageView extends AppCompatImageView implements View.OnTouchListener {
//set a default max and min dot size so user can change size of drawing line
private final int DEFAULT_DOT_SIZE = 10;
private final int MAX_DOT_SIZE = 100;
private final int MIN_DOT_SIZE = 10;
private int dotSize;

//Set default pen coulour
private int penColour;
private final int DEFAULT_COLOUR = Color.parseColor("#F82323");

//instead of having one path we can have multiple so each colour can be set to new paint object
private ArrayList<Path> pathsArrList;
private ArrayList<Paint> paintsArrList;

private Path path;
private Paint paint;

private float pointX, pointY, oldPointX, oldPointY;

//constructors
public PaintImageView(Context context) {
    super(context);
    this.initVariables();
}

public PaintImageView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    this.initVariables();
}

public PaintImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.initVariables();
}

public void setPenColour(int penColour) {
    this.penColour = penColour;

}

public int getPenColour() {
    return penColour;
}

//Initialize Instance variables
private void initVariables() {
    dotSize = DEFAULT_DOT_SIZE;
    penColour = DEFAULT_COLOUR;

    this.pathsArrList = new ArrayList<>();
    this.paintsArrList = new ArrayList<>();

    path = new Path();
    this.pointX = this.pointY = this.oldPointX = this.oldPointY = (float) 0.0;
    this.setOnTouchListener(this);

    this.addPath(false);
}

//Adds path and paint to ArrayLists
private void addPath(boolean fill){
    path = new Path();
    pathsArrList.add(path);
    paint = new Paint();
    paintsArrList.add(paint);

    paint.setColor(penColour);

    //Decide whether you want to fill cirlce or set stroke
    if(!fill){
        paint.setStyle(Paint.Style.STROKE);
        }

    paint.setStrokeWidth(dotSize);
}

public String getDotSize(){

    return String.valueOf(dotSize);
}

//Change size of line to draw
public void changeDotSize(int increment){
    this.dotSize += increment;
    this.dotSize = Math.max(dotSize,MIN_DOT_SIZE);
    this.dotSize = Math.min(dotSize,MAX_DOT_SIZE);
}

@Override
public void onDraw(Canvas canvas){
    super.onDraw(canvas);

    //iterate through arrLists and draw them all instead of one
    for(int i = 0; i < pathsArrList.size(); i++){
        canvas.drawPath(pathsArrList.get(i),paintsArrList.get(i));



    }
}

//Functionality for reset button
public void resetPaint(){
    this.initVariables();
    this.invalidate();
}

public void reDraw(){
    path = new Path();
    this.pointX = this.pointY = this.oldPointX = this.oldPointY = (float) 0.0;
    this.setOnTouchListener(this);

    this.addPath(false);
}

//Handle on touch Events for paint drawn by user
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
    pointX = motionEvent.getX();
    pointY = motionEvent.getY();

    switch(motionEvent.getAction()){
        case MotionEvent.ACTION_DOWN:
            this.addPath(true);
            this.path.addCircle(pointX,pointY,dotSize/2,Path.Direction.CW);
            this.addPath(false);
            this.path.moveTo(pointX,pointY);
            break;
            case MotionEvent.ACTION_MOVE:
                this.path.lineTo(pointX,pointY);
                break;
                case MotionEvent.ACTION_UP:
                    this.addPath(true);
                    if(oldPointX == pointX && oldPointY == pointY){
                        //If they match put a circle on screen at this location
                        this.path.addCircle(pointX,pointY,dotSize/2,Path.Direction.CW);
                    }
                    break;
    }

    this.invalidate();

    //update old values to new values to track on touch paint
    oldPointX = pointX;
    oldPointY = pointY;

    return true;
}

}

这是使用毕加索加载图像的类:

public class EditMapImage extends AppCompatActivity implements View.OnClickListener {

//Create new object of PaintImageView
private PaintImageView paintImageView;

PhotoViewAttacher photoViewAttacher;

//Instance Variables
//Find ImageButtons, Buttons, Textview and declare and initialise dot size increment values
private ImageButton saveMapButton, resetButton;
private Button redColourButton, purpleColourButton, greenColourButton, dotSizePlus, dotSizeMinus;
private TextView displayDotSize;
private static final int DOT_SIZE_INCREMENT = 10;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.map_edit_gallery);
    initializeVariables();

    checkIntent();


}

private void initializeVariables() {
    //Find buttons and associate with variables
    saveMapButton = findViewById(R.id.saveEditImagebutton);
    resetButton = findViewById(R.id.resetButton);
    redColourButton = findViewById(R.id.redButton);
    purpleColourButton = findViewById(R.id.purpleButton);
    greenColourButton = findViewById(R.id.greenButton);
    dotSizePlus = findViewById(R.id.dotPlusButton);
    dotSizeMinus = findViewById(R.id.dotMinusButton);

    //Set on click listeners
    saveMapButton.setOnClickListener(this);
    resetButton.setOnClickListener(this);
    redColourButton.setOnClickListener(this);
    purpleColourButton.setOnClickListener(this);
    greenColourButton.setOnClickListener(this);
    dotSizePlus.setOnClickListener(this);
    dotSizeMinus.setOnClickListener(this);

    paintImageView = findViewById(R.id.mapEditScreen);

    //Update textview dotSize with the current size of dot by increments
    displayDotSize = findViewById(R.id.dotSize);
    displayDotSize.setText(paintImageView.getDotSize());
}

//This will check to see if the intent extras exist and if they do get the extra
private void checkIntent(){
    if(getIntent().hasExtra("image_url") && getIntent().hasExtra("name_url")){

        String imageUrl = getIntent().getStringExtra("image_url");
        String nameUrl = getIntent().getStringExtra("name_url");

        setMapImage(imageUrl, nameUrl);

    }
}

Matrix matrix = new Matrix();

private void setMapImage(final String imageUrl, String nameUrl){

    //Set the Text view
    TextView name  = findViewById(R.id.mapNameEditor);
    name.setText(nameUrl);


    //Set the Image
    final PaintImageView imageView = findViewById(R.id.mapEditScreen);
    Picasso.get().load(imageUrl).fit().centerInside().into(imageView,new Callback.EmptyCallback() {
        //Will center image in middle of imageview with scale type matrix.
        @Override
        public void onSuccess() {
            Drawable d = imageView.getDrawable();

            RectF imageRectF = new RectF(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
            RectF viewRectF = new RectF(0, 0, imageView.getWidth(), imageView.getHeight());
            matrix.setRectToRect(imageRectF, viewRectF, Matrix.ScaleToFit.CENTER);
            imageView.setImageMatrix(matrix);
        }
    });

    //Implement zoom
    final Switch zoom = findViewById(R.id.zoomSwitch);

    zoom.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(zoom.isChecked()){
                photoViewAttacher = new PhotoViewAttacher(imageView);
                photoViewAttacher.setZoomable(true);
            }else{
                Matrix theMatrix = new Matrix();
                photoViewAttacher.getSuppMatrix(theMatrix);
                photoViewAttacher.setZoomable(false);
                photoViewAttacher.setDisplayMatrix(theMatrix);
                paintImageView.reDraw();

            }
        }
    });
}

//Gets called everytime a button is pressed
@Override
public void onClick(View view) {
    //Find which button was pressed

    switch(view.getId()){
        case R.id.redButton: paintImageView.setPenColour(Color.parseColor("#F82323"));
            paintImageView.getPenColour();
            Toast.makeText(this, "RED",Toast.LENGTH_SHORT).show();
            break;
        case R.id.purpleButton: paintImageView.setPenColour(Color.parseColor("#7C4DFF"));
            paintImageView.getPenColour();
            Toast.makeText(this, "PURPLE",Toast.LENGTH_SHORT).show();
            break;
        case R.id.greenButton: paintImageView.setPenColour(Color.parseColor("#00C853"));
            paintImageView.getPenColour();
            Toast.makeText(this, "GREEN",Toast.LENGTH_SHORT).show();
            break;
        case R.id.dotPlusButton: paintImageView.changeDotSize(+DOT_SIZE_INCREMENT);
            displayDotSize.setText(paintImageView.getDotSize());
            break;
        case R.id.dotMinusButton: paintImageView.changeDotSize(-DOT_SIZE_INCREMENT);
            displayDotSize.setText(paintImageView.getDotSize());
            break;
        case R.id.resetButton: paintImageView.resetPaint();
            displayDotSize.setText(paintImageView.getDotSize());
            Toast.makeText(this, "RESET",Toast.LENGTH_SHORT).show();
            break;
        case R.id.saveEditImagebutton:
            Toast.makeText(this, "SAVED",Toast.LENGTH_SHORT).show();
            break;

    }
}

}

android-studio drawable paint picasso android-photoview