我正在创建一个将图像加载到自定义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;
}
}
}