在 android 中绘制自定义图像视图
Draw on the custom image view in android
我正在开发一个绘图应用程序。而且我已经创建了一个允许用户在视图上绘制的绘图视图。
问题是,我在上面画的时候,超出了图片的面积(请参考图片,黄线超出了实际照片的面积),如何粘贴canvas实际图像的大小?
图像视图如何缩放?这意味着当用户点击笔按钮时,它会绘制,当用户再次点击时它会变成缩放功能。
谢谢。缩放功能可以稍后解决,超出区域的问题需要先解决
这是xml
中的自定义绘图视图
<com.example.tool.DrawView
android:id="@+id/draw"
android:layout_width="match_parent"
android:layout_height="match_parent" />
这是java
public class DrawView extends ImageView {
private int color = Color.BLACK;
private float width = 4f;
private List<Holder> holderList = new ArrayList<Holder>();
private class Holder {
Path path;
Paint paint;
Holder(int color, float width) {
path = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(width);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
}
}
public DrawView(Context context) {
super(context);
init();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
holderList.add(new Holder(color, width));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Holder holder : holderList) {
canvas.drawPath(holder.path, holder.paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
holderList.add(new Holder(color,width));
holderList.get(holderList.size() - 1).path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
holderList.get(holderList.size() - 1).path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
break;
default:
return false;
}
invalidate();
return true;
}
public void resetPaths() {
for (Holder holder : holderList) {
holder.path.reset();
}
invalidate();
}
public void setBrushColor(int color) {
this.color = color;
}
public void setWidth(float width) {
this.width = width;
}
}
我这样称呼它:
DrawView pic = findViewById(R.id.draw);
pic.setImageBitmap(bitmap);
非常感谢您的帮助
如果在 ImageView 的属性中有一个真正的属性 adjustViewBounds,您可以通过编程将 DrawView 的宽度设置为 ImageView 的宽度。
先计算显示图片的大小,然后将eventX和eventY钳制在显示图片的边界上。代码如下:
int imageViewH=imageView.getMeasuredHeight();//height of imageView
int imageViewW =imageView.getMeasuredWidth();//width of imageView
int drawableH =imageView.getDrawable().getIntrinsicHeight();//original height of underlying image
int drawableW=imageView.getDrawable().getIntrinsicWidth();//original width of underlying image
int displayH, displayW; // the shown height and width of the picture.
int leftX, rightX, topY, bottomY; // the shown edges of the picture.
if (imageViewH/drawableH <= imageViewW/drawableW){
displayW = drawableW*imageViewH/drawableH;//rescaled width of image within ImageView
displayH = imageViewH;
leftX = (imageViewW - displayW)/2; // left edge of the displayed image.
rightX = leftX + displayW; // right edge of the displayed image.
topY = 0; // top edg
bottomY = displayH; // bottom edge.
}else{
displayH = drawableH*imageViewW/drawableH;//rescaled height of image within ImageView
displayW = imageViewW;
leftX = 0; // left edge of the displayed image.
rightX = displayW; // right edge of the displayed image.
topY = (imageViewH - displayH)/2; // top edg
bottomY = topY + displayH; // bottom edge.
}
//TODO: clamp the eventX and eventY to the bound of leftX, rightX, topY, bottomY
注意:仅当您的 ImageView 具有测量高度和可绘制对象后,才应使用该代码。
我正在开发一个绘图应用程序。而且我已经创建了一个允许用户在视图上绘制的绘图视图。
问题是,我在上面画的时候,超出了图片的面积(请参考图片,黄线超出了实际照片的面积),如何粘贴canvas实际图像的大小?
图像视图如何缩放?这意味着当用户点击笔按钮时,它会绘制,当用户再次点击时它会变成缩放功能。
谢谢。缩放功能可以稍后解决,超出区域的问题需要先解决
这是xml
中的自定义绘图视图 <com.example.tool.DrawView
android:id="@+id/draw"
android:layout_width="match_parent"
android:layout_height="match_parent" />
这是java
public class DrawView extends ImageView {
private int color = Color.BLACK;
private float width = 4f;
private List<Holder> holderList = new ArrayList<Holder>();
private class Holder {
Path path;
Paint paint;
Holder(int color, float width) {
path = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(width);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
}
}
public DrawView(Context context) {
super(context);
init();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
holderList.add(new Holder(color, width));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (Holder holder : holderList) {
canvas.drawPath(holder.path, holder.paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
holderList.add(new Holder(color,width));
holderList.get(holderList.size() - 1).path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
holderList.get(holderList.size() - 1).path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
break;
default:
return false;
}
invalidate();
return true;
}
public void resetPaths() {
for (Holder holder : holderList) {
holder.path.reset();
}
invalidate();
}
public void setBrushColor(int color) {
this.color = color;
}
public void setWidth(float width) {
this.width = width;
}
}
我这样称呼它:
DrawView pic = findViewById(R.id.draw);
pic.setImageBitmap(bitmap);
非常感谢您的帮助
如果在 ImageView 的属性中有一个真正的属性 adjustViewBounds,您可以通过编程将 DrawView 的宽度设置为 ImageView 的宽度。
先计算显示图片的大小,然后将eventX和eventY钳制在显示图片的边界上。代码如下:
int imageViewH=imageView.getMeasuredHeight();//height of imageView
int imageViewW =imageView.getMeasuredWidth();//width of imageView
int drawableH =imageView.getDrawable().getIntrinsicHeight();//original height of underlying image
int drawableW=imageView.getDrawable().getIntrinsicWidth();//original width of underlying image
int displayH, displayW; // the shown height and width of the picture.
int leftX, rightX, topY, bottomY; // the shown edges of the picture.
if (imageViewH/drawableH <= imageViewW/drawableW){
displayW = drawableW*imageViewH/drawableH;//rescaled width of image within ImageView
displayH = imageViewH;
leftX = (imageViewW - displayW)/2; // left edge of the displayed image.
rightX = leftX + displayW; // right edge of the displayed image.
topY = 0; // top edg
bottomY = displayH; // bottom edge.
}else{
displayH = drawableH*imageViewW/drawableH;//rescaled height of image within ImageView
displayW = imageViewW;
leftX = 0; // left edge of the displayed image.
rightX = displayW; // right edge of the displayed image.
topY = (imageViewH - displayH)/2; // top edg
bottomY = topY + displayH; // bottom edge.
}
//TODO: clamp the eventX and eventY to the bound of leftX, rightX, topY, bottomY
注意:仅当您的 ImageView 具有测量高度和可绘制对象后,才应使用该代码。