android - 在 Android 中使用缩放查看并在 Canvas 上画线

标签 android canvas touch imageview paint

我正在 Canvas 上工作。如下图所示, View 类用于缩放和画线。单击缩放按钮时捏缩放工作正常。但是当我单击绘画按钮时,我传递一个 bool 值作为 true,它在触摸时画线手指。但在图像上画线后,我想在图像的特定位置用这条画线再次开始缩放(用画线缩放+图像1)Zoom Image)2)with paint . 现在我想开始缩放图像 2,如绘画图像所示。我尝试搜索但仍然没有成功。 谢谢

public class DemoView extends View {

    private static final float STROKE_WIDTH = 5f;

    /** Need to track this so the dirty region can accommodate the stroke. **/
    private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;

    private Paint paint = new Paint();
    private Path path = new Path();



    // These matrices will be used to move and zoom image
        Matrix matrix = new Matrix();
        Matrix savedMatrix = new Matrix();

        // We can be in one of these 3 states
        static final int NONE = 0;
        static final int DRAG = 1;
        static final int ZOOM = 0;
        public static float xValue;
        public static float yValue;
        private static final float MAX_ZOOM = 10;
        int mode = NONE;

        // Remember some things for zooming
        PointF start = new PointF();
        PointF mid = new PointF();
        float oldDist = 1f;
        private float globalX;
        private float globalY;
        private float width;
        private float height;

    /**
     * Optimizes painting by invalidating the smallest possible area.
     */
    private float lastTouchX;
    private float lastTouchY;
    private final RectF dirtyRect = new RectF();

    private boolean flag;

    private Bitmap bgBitmap;
    private float mScaleFactor;

    private int mActivePointerId;

    private float mPosX;

    private float mPosY;

    public DemoView(Context context, AttributeSet attrs) {
        super(context, attrs);

        paint.setAntiAlias(true);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(STROKE_WIDTH);
        bgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.nat);
    }
    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        canvas.save();
        canvas.translate(mPosX, mPosY);
        canvas.scale(mScaleFactor, mScaleFactor);

        canvas.drawBitmap(bgBitmap, 0,0,null);
        if(mScaleFactor != 1.f)
            canvas.restore();

        if(flag)
            canvas.drawPath(path,paint);

        if(mScaleFactor == 1.f)
            canvas.restore();
    }

    /**
     * Erases the signature.
     */
    public void clear() {
        path.reset();

        // Repaints the entire view.
        invalidate();
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float eventX = event.getX();
        float eventY = event.getY();


        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (flag) {
                path.moveTo(eventX, eventY);
                lastTouchX = eventX;
                lastTouchY = eventY;
                // There is no end point yet, so don't waste cycles invalidating.
                return true;
            }else{
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                mActivePointerId = event.getPointerId(0);
                break;
            }

        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            if (oldDist > 10f) {
                savedMatrix.set(matrix);
                midPoint(mid, event);
                mode = ZOOM;
            }
            break;
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            break;
        case MotionEvent.ACTION_MOVE:
        case MotionEvent.ACTION_UP:
            if (flag) {
                resetDirtyRect(eventX, eventY);

                // When the hardware tracks events faster than they are delivered,
                // the
                // event will contain a history of those skipped points.
                int historySize = event.getHistorySize();
                for (int i = 0; i < historySize; i++) {
                    float historicalX = event.getHistoricalX(i);
                    float historicalY = event.getHistoricalY(i);
                    expandDirtyRect(historicalX, historicalY);
                    path.lineTo(historicalX, historicalY);
                }

                // After replaying history, connect the line to the touch point.
                path.lineTo(eventX, eventY);
                break;
            }else{
                // Start tracking the dirty region.
                if (mode == DRAG) {
                    // ...
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY()
                            - start.y);
                } else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
//                  final int pointerIndex = event.findPointerIndex((Integer) mActivePointerId);
//                  final float x = event.getX(pointerIndex);
//                  final float y = event.getY(pointerIndex);
//
//                  final float dx = x - globalX;
//                  final float dy = y - globalY;
//                  mPosX += dx;
//                  mPosY += dy;
                }
            }

        default:
            Log.e("Ignored touch event: " ,"i"+ event.toString());
            return false;
        }

        // Include half the stroke width to avoid clipping.
        invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH),
                (int) (dirtyRect.top - HALF_STROKE_WIDTH),
                (int) (dirtyRect.right + HALF_STROKE_WIDTH),
                (int) (dirtyRect.bottom + HALF_STROKE_WIDTH));

        lastTouchX = eventX;
        lastTouchY = eventY;

        return true;
    }

    /**
     * Called when replaying history to ensure the dirty region includes all
     * points.
     */
    private void expandDirtyRect(float historicalX, float historicalY) {
        if (historicalX < dirtyRect.left) {
            dirtyRect.left = historicalX;
        } else if (historicalX > dirtyRect.right) {
            dirtyRect.right = historicalX;
        }
        if (historicalY < dirtyRect.top) {
            dirtyRect.top = historicalY;
        } else if (historicalY > dirtyRect.bottom) {
            dirtyRect.bottom = historicalY;
        }
    }

    /**
     * Resets the dirty region when the motion event occurs.
     */
    private void resetDirtyRect(float eventX, float eventY) {

        // The lastTouchX and lastTouchY were set when the ACTION_DOWN
        // motion event occurred.
        dirtyRect.left = Math.min(lastTouchX, eventX);
        dirtyRect.right = Math.max(lastTouchX, eventX);
        dirtyRect.top = Math.min(lastTouchY, eventY);
        dirtyRect.bottom = Math.max(lastTouchY, eventY);
    }


    /** Determine the space between the first two fingers */
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    /** Calculate the mid point of the first two fingers */
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }

    public boolean setFlag(boolean b) {
        return flag = b;
    }
}

最佳答案

我不确定我是否理解你的问题,但你应该使用 ScaleGestureDetector如此处所述:http://developer.android.com/training/gestures/scale.html

关于android - 在 Android 中使用缩放查看并在 Canvas 上画线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16541065/

相关文章:

javascript - 在 HTML Canvas 上绘制线性渐变路径

html - 有没有一个好的开源谷歌地图风格 <canvas> 图像组件?

c# - 统一触控输入

android - 在 android 中从哪里开始翻页效果?

android - Android 中如何切换标签页?

java - 如何一键停止两个可运行程序?

java - eclipse 中的 Junit 在使用 junit 时产生 NoClassDefFoundError

javascript - 我无法使用 Canvas 从 blob URL 中裁剪图像

Javascript Canvas 选择器

javascript - 滑动时防止触摸启动