【问题标题】:Android drawing on a bitmap on a canvas after pinch zoom捏缩放后Android在画布上的位图上绘图
【发布时间】:2016-09-26 00:24:24
【问题描述】:

我有一个自定义绘图视图,它基本上在画布上绘制位图,然后我可以使用泛洪填充算法在位图上进行绘制。我正在尝试实现捏缩放功能。用户缩放后,我希望他们也能够在缩放位置进行绘制。这是我的 onDraw() 代码:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    canvas.scale(mScaleFactor, mScaleFactor,mScaleX,mScaleY);
    canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
    drawCanvas = new Canvas(canvasBitmap);
    canvas.restore();
}

onTouchEvent():

public boolean onTouchEvent(MotionEvent event) {
//detect user touch

    if(event.getPointerCount()>1) {
        mScaleDetector.onTouchEvent(event);
        invalidate();
        return true;
    }
    else {
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //drawPath.moveTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                //drawPath.lineTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                final Point p1 = new Point();
                float x0=touchX-mScaleX;
                float y0=touchY-mScaleY;
                x0=x0*mScaleFactor;
                y0=y0*mScaleFactor;
                x0+=mScaleX;
                y0+=mScaleY;
                p1.x = (int) x0;
                p1.y = (int) y0;
                Log.d("Pixel coordinates",p1.x+" "+p1.y);
                Log.d("touch co-ordinates", touchX+" "+touchY);
                Log.d("pivot points", mScaleX+" "+mScaleY);
                Log.d("Scalefactor", Float.toString(mScaleFactor));
                int pixel = canvasBitmap.getPixel(p1.x, p1.y);
                prev_bitmap = canvasBitmap.copy(Bitmap.Config.ARGB_8888, true);
                bitMapStack.push(prev_bitmap);
                floodFill(canvasBitmap, p1, pixel, paintColor);
                break;
            default:
                return false;

        }
    }
    invalidate();
    return true;
}

比例监听器:

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        mScaleFactor *= detector.getScaleFactor();
        mScaleX=detector.getFocusX();
        mScaleY=detector.getFocusY();
        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(1f, Math.min(mScaleFactor, 5.0f));


        invalidate();
        return true;
    }
}

每当我尝试缩放时,我的应用程序都会失败并收到以下消息:

致命异常:主要 进程:com.example.dhruv.coloringbook,PID:14161 java.lang.IllegalArgumentException: y 必须是

我不确定为什么会发生这种情况,因为在缩放手势期间甚至不应该调用 getPixel,而且我也不知道为什么我的 y 坐标超出了位图的范围。我该如何解决这个问题/同一件事是否有更好的实现?

编辑:完整的堆栈跟踪: 09-25 16:44:48.456 16730-16730/com.example.dhruv.coloringbook D/像素坐标:1080 2768 09-25 16:44:48.457 16730-16730/com.example.dhruv.coloringbook D/触摸坐标:106.0 724.0 09-25 16:44:48.457 16730-16730/com.example.dhruv.coloringbook D/枢轴点:651.0 864.5 09-25 16:44:48.457 16730-16730/com.example.dhruv.coloringbook D/Scalefactor: 2.2871902 09-25 16:44:48.457 16730-16730/com.example.dhruv.coloringbook E/InputEventReceiver:异常调度输入事件。 09-25 16:44:48.457 16730-16730/com.example.dhruv.coloringbook E/MessageQueue-JNI:MessageQueue 回调中的异常:handleReceiveCallback 09-25 16:44:48.459 16730-16730/com.example.dhruv.coloringbook E/MessageQueue-JNI: java.lang.IllegalArgumentException: y 必须是

【问题讨论】:

  • 发布完整的堆栈跟踪,这样我们就可以看到崩溃的逻辑流程。部分堆栈跟踪不足以完全说明发生了什么,尤其是当它在框架代码中崩溃时。
  • 已编辑以添加完整跟踪

标签: android canvas bitmap drawing scaling


【解决方案1】:

因此,想象一下您正在捏紧缩放。您放下手指 1。我们将此视为向下。你放下手指 2- 现在我们看到 2 个指针向下。我们离开了手指 2。我们现在又向下了 1 个指针。我们抬起手指 1- 我们得到一个动作,但我们只看到 1 个指针向下(因为另一个指针已经被抬起)。所以我们把它当作一根手指向上。为防止这种情况发生,您需要跟踪此触摸中是否有两根手指向下。

这就解释了为什么 getPixel 在缩放中被调用。至于为什么会崩溃——缩放后的像素位置比画布位图大。修复上述问题可能会也可能不会修复,因为我不知道您使用什么逻辑来调整 canvasBitmap 的大小/大小。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 2012-10-06
相关资源
最近更新 更多