如何在带有画布的可缩放图像视图上正确绘制onTouch事件?

时间:2015-05-13 09:42:44

标签: android canvas bitmap

我正在尝试使用可追踪/可缩放的Imageview在Canvas上使用onTouch事件进行绘制。如果图像是全屏的(并且与屏幕大小成比例),它可以很好地工作,但是一旦放大图像,绘图点就不会与触摸屏幕的位置相同。 Something like this

我正在创建画布和图像视图:

                    canvas = new Canvas(bitmap);
                    image.setImageBitmap(bitmap);

然后使用setMatrix上的image执行大量捏合/缩放转换。通过查看bitmap.getHeight()bitmap.getWidth(),很明显,在所有转换过程中,BitmapImage的实际大小都没有变化。例如,图像保持不变2560x1454,而位图保持在3264x1836(对于这些值使用image.getHeight()/width()bitmap.getHeight()/width())。

对于绘图部分,我将MotionEvent转换为一系列Point对象(字面上只是int xint y),然后通过我在某处找到的公式转换该值互联网。我真的不知道它为什么会起作用,这可能是我的第一个问题。

   List<Point> points = new ArrayList<>();
   private boolean handleDraw(View v, MotionEvent event) {
    if (event.getAction() != MotionEvent.ACTION_UP) {
        Point p = new Point();
        p.x = event.getX();
        p.y = event.getY();

        convertPoint(p, v);
        points.add(p);

        //draw the converted points
        drawOnBitmap();
        return true;
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        points.clear();
        return true;
    }
    return true;
}

然后将它们转换为位图值

 //v here is the view passed by the ontouch listener.
 private void convertPoint(Point point, View v) {

    double divisor = ((double) bitmap.getWidth() / (double) v.getWidth());

    point.x = (int) ((double) point.x * divisor);
    point.y = (int) ((double) point.y * divisor);
 }

并在画布上绘制:

private void drawOnBitmap() {
    Path path = new Path();

    boolean first = true;
    //uses quaddraw
    for (int i = 0; i < points.size(); i += 2) {
        Point point = points.get(i);
        if (first) {
            first = false;
            path.moveTo(point.x, point.y);
        } else if (i < points.size() - 1) {
            Point next = points.get(i + 1);
            path.quadTo(point.x, point.y, next.x, next.y);
        } else {
            path.lineTo(point.x, point.y);
        }
    }

    canvas.drawPath(path, redPaint);
    image.invalidate();

}

使用Paint

    redPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    redPaint.setStyle(Paint.Style.STROKE);
    redPaint.setStrokeWidth(STROKE_WIDTH);
    redPaint.setColor(Color.RED);

一般情况下,正在发生的事情是触摸事件正在从屏幕大小缩放到位图大小(有关示例,请参见上图)。但是,答案不仅仅是采用原始getRaw()值;那些总是不正确的。

我想问题是,如何让画布响应触摸事件的ABSOLUTE位置而不是比例?如果不这样做,我怎样才能使用与imageview相同的值来转换基础画布并使它们按比例缩放?

1 个答案:

答案 0 :(得分:2)

您需要使用<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.0.7</version> </dependency> 使用以下代码重新计算您的坐标:

Matrix

您可以获得完整的样本here