Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在检测到onTouch的点绘制一个小矩形_Android_Imageview_Ontouch - Fatal编程技术网

Android 在检测到onTouch的点绘制一个小矩形

Android 在检测到onTouch的点绘制一个小矩形,android,imageview,ontouch,Android,Imageview,Ontouch,我正在执行一个非常小的测试来调试一些更大的东西,我很难找出是什么导致了这个问题 我有一个图像视图,一个画布和一个位图。我初始化ImageView并将其设置为位图,然后将画布设置为位图,如下所示: _image.setImageBitmap(bitmap); Canvas canvas = new Canvas(bitmap); Rect rect = new Rect((int)event.getX(),event.getY(),event.getX()+20,event.getY()+20)

我正在执行一个非常小的测试来调试一些更大的东西,我很难找出是什么导致了这个问题

我有一个图像视图,一个画布和一个位图。我初始化ImageView并将其设置为位图,然后将画布设置为位图,如下所示:

_image.setImageBitmap(bitmap);
Canvas canvas = new Canvas(bitmap);
Rect rect = new Rect((int)event.getX(),event.getY(),event.getX()+20,event.getY()+20);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(rect,paint);
然后我将一个onTouchListener附加到_图像,并监听MotionEvent.ACTION_是否被检测到。在这一点上,我在画布上绘制了一个矩形,如下所示:

_image.setImageBitmap(bitmap);
Canvas canvas = new Canvas(bitmap);
Rect rect = new Rect((int)event.getX(),event.getY(),event.getX()+20,event.getY()+20);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(rect,paint);
我尝试过使用不同大小的位图图像,比全屏幕小,接近精确大小,甚至更大,但我永远无法在手指接触屏幕的地方绘制矩形。我在getX()上尝试了不同的转换,试图从dp转换为dp,使用getRawX/Y();基本上是一堆不同的解决方案,没有一个有效。我试着得到位图大小与屏幕大小的比率,然后乘以/除以它;没有什么能够解决这个非常简单的问题

很可能我在某个时候尝试了正确的方法,但只是错误地实现了它。我真的很感激一些关于是什么导致Rect在它所在的位置绘制的建议,需要什么转换才能使它在触摸发生的位置绘制,以及为什么。“为什么”是因为我想从中学习

编辑:这是所发生情况的近似值。红色矩形是实际触摸发生的位置,蓝色矩形是绘制触摸的位置。它从X=Y=0开始缩放。此外,我刚刚注意到,它还根据您使用的图像的宽度和高度进行缩放


我想象你的实际位图比视图大,并且缩小了。由于您使用位图的坐标绘制,并且位图正在缩小,因此位置也将缩小以匹配

您更可能想做的是创建ImageView的子类,然后根据onTouchEvent()中接收到的位置在onDraw()中绘制Rect。或者,您可以做一些数学运算,计算出位图相对于视图大小的比例,并按相反的比例放大坐标。此可触摸ImageView的快速实现如下所示:

public class DrawableImageView extends ImageView {
    private final int mRectSize;
    private final Paint mPaint;
    private final Rect mRect = new Rect();

    public DrawableImageView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mRectSize = (int) (getResources().getDisplayMetrics().density * 20);
    }

    // Other constructors omitted for brevity

    @Override public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mRect.set(x, y, x + mRectSize, y + mRectSize);
            mRect.offset(-(mRectSize / 2), -(mRectSize / 2));

            invalidate();
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRect, mPaint);
    }
}

我会想象你的实际位图比视图大,并且缩小了。由于您使用位图的坐标绘制,并且位图正在缩小,因此位置也将缩小以匹配

您更可能想做的是创建ImageView的子类,然后根据onTouchEvent()中接收到的位置在onDraw()中绘制Rect。或者,您可以做一些数学运算,计算出位图相对于视图大小的比例,并按相反的比例放大坐标。此可触摸ImageView的快速实现如下所示:

public class DrawableImageView extends ImageView {
    private final int mRectSize;
    private final Paint mPaint;
    private final Rect mRect = new Rect();

    public DrawableImageView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mRectSize = (int) (getResources().getDisplayMetrics().density * 20);
    }

    // Other constructors omitted for brevity

    @Override public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mRect.set(x, y, x + mRectSize, y + mRectSize);
            mRect.offset(-(mRectSize / 2), -(mRectSize / 2));

            invalidate();
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRect, mPaint);
    }
}

我会想象你的实际位图比视图大,并且缩小了。由于您使用位图的坐标绘制,并且位图正在缩小,因此位置也将缩小以匹配

您更可能想做的是创建ImageView的子类,然后根据onTouchEvent()中接收到的位置在onDraw()中绘制Rect。或者,您可以做一些数学运算,计算出位图相对于视图大小的比例,并按相反的比例放大坐标。此可触摸ImageView的快速实现如下所示:

public class DrawableImageView extends ImageView {
    private final int mRectSize;
    private final Paint mPaint;
    private final Rect mRect = new Rect();

    public DrawableImageView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mRectSize = (int) (getResources().getDisplayMetrics().density * 20);
    }

    // Other constructors omitted for brevity

    @Override public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mRect.set(x, y, x + mRectSize, y + mRectSize);
            mRect.offset(-(mRectSize / 2), -(mRectSize / 2));

            invalidate();
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRect, mPaint);
    }
}

我会想象你的实际位图比视图大,并且缩小了。由于您使用位图的坐标绘制,并且位图正在缩小,因此位置也将缩小以匹配

您更可能想做的是创建ImageView的子类,然后根据onTouchEvent()中接收到的位置在onDraw()中绘制Rect。或者,您可以做一些数学运算,计算出位图相对于视图大小的比例,并按相反的比例放大坐标。此可触摸ImageView的快速实现如下所示:

public class DrawableImageView extends ImageView {
    private final int mRectSize;
    private final Paint mPaint;
    private final Rect mRect = new Rect();

    public DrawableImageView(Context context) {
        super(context);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.RED);
        mRectSize = (int) (getResources().getDisplayMetrics().density * 20);
    }

    // Other constructors omitted for brevity

    @Override public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            final int x = (int) event.getX();
            final int y = (int) event.getY();

            mRect.set(x, y, x + mRectSize, y + mRectSize);
            mRect.offset(-(mRectSize / 2), -(mRectSize / 2));

            invalidate();
            return true;
        } else {
            return super.onTouchEvent(event);
        }
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(mRect, mPaint);
    }
}

所以,我相信我已经算出了数学,它允许我将onTouch坐标变换到画布上

我真正想走这条路线(与ImageView的自定义子类相反)的原因是,我对矩形的绘制并不感兴趣:我更感兴趣的是将这些坐标精确地映射到位图中特定的OCRD文本字符串上。我做这个练习的原因是为了弄清楚为什么触摸没有被归因于正确的文本行,我使用绘制的矩形来估计触摸被记录的位置

因此,关于数学,结果比我想象的要简单得多:

int x1 = (int)(event.getX() * ((float) canvas.getWidth() / _image.getRight()));
int y1 = (int)(event.getY() * ((float) canvas.getHeight() / _image.getBottom()));
我将onTouch坐标乘以画布的尺寸与ImageView的尺寸之比,然后将其转换为浮点数。将其绘制如下:

rect = new Rect(x1-10,y1-10,x1+10,y1+10);
    //I took the advice about centering the Rect around the touch for clarity
paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(rect,paint);
无论位图大小如何,Rect都是触摸的精确位置

我觉得很有趣,它没有引起我打电话给的任何问题

_image.setAdjustViewBounds(true);
在我的程序的前面,我这样做是为了从位图中删除一些填充(由于某种原因,可能是由于缩放)。同样有趣的是,ImageView包含在ScrollLayout中,但即使图像足够大,可以滚动,它似乎也不需要考虑滚动位移


感谢KCopock花时间帮助我,也感谢另一位用户(当他意识到自己误解了我时,他的评论被删除了)花时间帮助我。

所以,我相信我已经算出了允许我将onTouch坐标转换到画布上的数学

我真正想走这条路线的原因(相对于ImageView的自定义子类)是因为我对