Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
655 views
in Technique[技术] by (71.8m points)

android-studio - 用手指在自定义imageview上绘图(Drawing with finger over custom imageview)

I am creating an app that loads an image into a custom imageview.

(我正在创建一个将图像加载到自定义imageview的应用程序。)

This custom imageview allows the user to draw with their finger over the image.

(这个自定义的imageview允许用户用手指在图像上绘制。)

The image is loaded into an imageview with picasso.

(图像将通过毕加索加载到imageview中。)

Everything works fine but I am using photoview to zoom but when zoomed in the drawn line on the image does scale with the zoom.

(一切正常,但是我正在使用photoview进行缩放,但是当放大图像上的绘制线时,会随着缩放而缩放。)

Is there any way to achieve this?

(有什么办法可以做到这一点?)

No zoom applied:

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

Zoom applied:

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

As you can see the red circle does not scale with the image, I would like it to be tied to the image some how.

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

Here is my custom imageview that handles all the drawing:

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

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;
}

}

(})

Here is the classthat uses picasso to load image:

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

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;

    }
}

}

(})

  ask by Space junkie translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...