使用ImageView和矩阵在图像上绘制图形
我们正在经历大约一周的以下问题: 我们正在绘制一幅图像,我们希望能够在用户的屏幕上重新缩放和“移动”。 为了达到这个目的,我们使用了ImageView和Matrix:它效果很好。使用ImageView和矩阵在图像上绘制图形
但是,现在我们正在寻找在背景图像上绘制一些矩形。 这些矩形必须重新缩放并与背景图片一起转换......我们遇到的问题是,当我们创建形状并使用以下代码进行绘制时,它将绘制在图像的左上角部分就像整个用户的屏幕被解释为其真实维度的一部分一样......?
我定制的ImageView
public class EnvironmentView extends ImageView {
Matrix matrix;
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
int viewWidth, viewHeight;
static final int CLICK = 3;
float saveScale = 1f;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight;
public static boolean EDIT_RISKYZONE = false;
static boolean SAVE = false;
ScaleGestureDetector mScaleDetector;
Context context;
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(3);
paint.setAlpha(80);
float left = 0;
float top = 0;
float right = getWidth();
float down = getHeight();
RectF origRect = new RectF(left, top, right, down);
matrix.mapRect(origRect);
canvas.drawRect(origRect, paint);
}
public EnvironmentView(Context context) {
super(context);
sharedConstructing(context);
}
public EnvironmentView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructing(context);
}
private void sharedConstructing(Context context) {
super.setClickable(true);
this.context = context;
matrix = new Matrix();
m = new float[9];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX);
}
public void setMaxZoom(float x) {
maxScale = x;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec);
//
// Rescales image on rotation
//
if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
|| viewWidth == 0 || viewHeight == 0)
return;
oldMeasuredHeight = viewHeight;
oldMeasuredWidth = viewWidth;
if (saveScale == 1) {
//Fit to screen.
float scale;
Drawable drawable = getDrawable();
if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)
return;
int bmWidth = drawable.getIntrinsicWidth();
int bmHeight = drawable.getIntrinsicHeight();
Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);
float scaleX = (float) viewWidth/(float) bmWidth;
float scaleY = (float) viewHeight/(float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
// Center the image
float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 2;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = viewWidth - 2 * redundantXSpace;
origHeight = viewHeight - 2 * redundantYSpace;
setImageMatrix(matrix);
}
}
}
屏幕输出
下面是什么在用户的屏幕上显示的屏幕截图,他已经绘制了屏幕的中央矩形之后,他们应该是约3/4的屏幕宽度和高度。
谢谢您的帮助!
图像需要从原点开始(左上角--0,0)。矩形应该从屏幕的中心开始宽度的一半,高度的一半。
int x = (widthOfScreen - widthOfRect)/2;
int y = (heightOfScreen - heightOfRect)/2;
所以我认为你需要另一个矩阵。首先转换第二个矩阵,以便将矩形放置在屏幕的中心,然后将相同的操作应用于另一个矩阵。在应用任何其他矩阵操作(即将它们全部注释掉)之前尝试做到这一点,并看到它将矩形放置在正确的位置。那么如果是对的,它应该缩放OK。
它的工作原理!非常感谢你!现在,我可以在背景图片上创建我的矩形,然后放大,缩小,翻译整个东西......太棒了:)谢谢,真的!因为我没有足够的声望,所以我不能“回答”你的答案......但是,还有一件事:当我在代码中放回缩放函数时,以及当我在缩放环境中工作时,我只需要创建矩形“转换”(意味着缩放+翻译)...我的意思是:如果我在缩放环境后绘制矩形,则不会在我期望的位置绘制矩形(正好在我的手指下) ... – Ark4ntes 2013-02-25 11:32:07
是的,我的逻辑中可能存在错误,我描述的翻译可能需要在最后而不是开始处完成,并且基于矩形的最终大小而不是开始处的大小。如果你不能把它整理成仅仅是最小的onDraw()而没有任何其他方法,那么任何人都可以将它粘贴到他们的Android应用程序的onDraw()中,并用它提出一个新的问题。 – 2013-02-25 12:07:34
你好,如答案中给出的,我拿了另一个矩阵,并将另一个矩阵转换为x和y的位置。但是我的矩形显示在右下方。 // inDraw 'newmatrix。setTranslate(x,y)' 'newmatrix.mapRect(origRect)' 其实我是新手,请指导我出错的地方。 – Dory 2013-04-24 12:30:43
你可以使用一个简单的onDraw()方法替换上面的所有代码:一个imageView,一个固定的矩形和一个演示该问题的矩阵? – 2013-02-25 09:10:41
可能问题在于图像和矩形从不同的角度开始,所以您可能需要两个基本上应用了相同的操作但基本不同的基础? – 2013-02-25 09:18:58
嗯......我只是做了你说的,我更新了我的文章(包括代码和屏幕截图),以便你可以看到究竟是不是按预期工作(或...?)。 – Ark4ntes 2013-02-25 09:49:07