android 在画布上缩放和变换的图像上绘制线

发布于 2024-12-27 05:18:00 字数 493 浏览 1 评论 0 原文

我在画布上缩放和变换后的图像上绘制线条时遇到问题,对于变换后的图像,我可以在图像上绘制线条,但如果图像缩放(放大或缩小),则使用手指触摸意外绘制线条像素。由于我正在研究绘画应用程序,但对此没有更多的了解,所以我需要您的帮助,我在谷歌上搜索了它,但没有运气,我

在这里没有找到任何东西,第一张图像默认工作正常,在第二个移动图像工作正常,正确绘制了线条

在此处输入图像描述 “在此处输入图像描述”

而在第三个缩放图像上无法正确绘制,我的意思是如果从左上角/左上角开始绘制,则绘制的线点会有所不同,如下所示

在此处输入图像描述

如果您需要代码,请说出来,我将编辑问题

I have problem to draw line on scaled and transformed image on canvas, well for the transformed I am able to draw line on image but if the image was scaled(zoom in or out) then line drew unexpectedly pixel using finger touch. As I am working on paint application but didn't have knowledge more about this so I need your help, I have searched it on google but no luck, I didn't found any thing

here is the images 1st is default working properly and in second moved image working properly drew the line properly

enter image description here enter image description here

while in third on scaled image not properly draw, I mean if start draw from the top/left corner then the line drew point was different like here

enter image description here

if you need for code then say it I'll edit the question

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青衫负雪 2025-01-03 05:18:00

好吧,经过多次实施,我得到了解决方案。

这是我在 onDraw() 中绘图的代码,

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);

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

    if(isDrawing)
        canvas.drawPath(tempPath,get_paint());

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

在这里您必须检查比例因子值以恢复画布。如果比例因子值默认为 1.f 并且图像刚刚移动,则在绘制线/路径后恢复,如果比例因子不等于 1.f(默认),则首先恢复画布,然后绘制线/使用手指触摸绘制时的路径。

这是我的 onTouch() 代码

@Override
public boolean onTouchEvent(MotionEvent ev) {
    mScaleDetector.onTouchEvent(ev);
    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();

        if(isDrawing){
            float dx = ev.getX();
            float dy = ev.getY();;

            if(mScaleFactor==1.f){
                dx = ev.getX() - mPosX;
                dy = ev.getY() - mPosY;
            }
            tempPath = new Path();
            tempPath.moveTo(dx,dy);
        }else{
            mLastTouchX = x;
            mLastTouchY = y;
            // Save the ID of this pointer
            mActivePointerId = ev.getPointerId(0);
        }
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        // Find the index of the active pointer and fetch its position
        if(isDrawing){
            float dx = ev.getX();
            float dy = ev.getY();;

            if(mScaleFactor==1.f){
                dx = ev.getX() - mPosX;
                dy = ev.getY() - mPosY;
            }
            tempPath.lineTo(dx,dy);
        }else{
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            mLastTouchX = x;
            mLastTouchY = y;
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        points.clear();
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        if(!isDrawing){
            // Extract the index of the pointer that left the touch sensor
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
        }
        break;
    }
    }
    invalidate();
    return true;
}

Ok after many implementation I got the solution for this.

This is my code for drawing in onDraw()

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.save();
    canvas.translate(mPosX, mPosY);
    canvas.scale(mScaleFactor, mScaleFactor);

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

    if(isDrawing)
        canvas.drawPath(tempPath,get_paint());

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

here you have to check for the scale factor value for restore the canvas. If the scale factor value was default that is 1.f and image was just move then restore after the draw line/path, if the scale factor was not equals to the 1.f (default) then restore the canvas 1st then draw line/path at using finger touch drawing time.

here is my onTouch() code

@Override
public boolean onTouchEvent(MotionEvent ev) {
    mScaleDetector.onTouchEvent(ev);
    final int action = ev.getAction();
    switch (action & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN: {
        final float x = ev.getX();
        final float y = ev.getY();

        if(isDrawing){
            float dx = ev.getX();
            float dy = ev.getY();;

            if(mScaleFactor==1.f){
                dx = ev.getX() - mPosX;
                dy = ev.getY() - mPosY;
            }
            tempPath = new Path();
            tempPath.moveTo(dx,dy);
        }else{
            mLastTouchX = x;
            mLastTouchY = y;
            // Save the ID of this pointer
            mActivePointerId = ev.getPointerId(0);
        }
        break;
    }

    case MotionEvent.ACTION_MOVE: {
        // Find the index of the active pointer and fetch its position
        if(isDrawing){
            float dx = ev.getX();
            float dy = ev.getY();;

            if(mScaleFactor==1.f){
                dx = ev.getX() - mPosX;
                dy = ev.getY() - mPosY;
            }
            tempPath.lineTo(dx,dy);
        }else{
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            final float x = ev.getX(pointerIndex);
            final float y = ev.getY(pointerIndex);

            final float dx = x - mLastTouchX;
            final float dy = y - mLastTouchY;

            mPosX += dx;
            mPosY += dy;

            mLastTouchX = x;
            mLastTouchY = y;
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        points.clear();
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_CANCEL: {
        mActivePointerId = INVALID_POINTER_ID;
        break;
    }

    case MotionEvent.ACTION_POINTER_UP: {
        if(!isDrawing){
            // Extract the index of the pointer that left the touch sensor
            final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = ev.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchX = ev.getX(newPointerIndex);
                mLastTouchY = ev.getY(newPointerIndex);
                mActivePointerId = ev.getPointerId(newPointerIndex);
            }
        }
        break;
    }
    }
    invalidate();
    return true;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文