在Android中删除旋转的图像不会显示擦除正确的路径

Her*_*u S 8 java android image imageview

我们正在构建一个涉及图像编辑的Android应用程序.一些功能包括旋转图像和擦除图像的一部分.

我们使用以下库:https://github.com/nimengbo/StickerView

我们已成功创建了一个旋转和擦除图像的功能.但是,当我们尝试执行以下操作时:

  1. 在一定程度上旋转图像.
  2. 然后,删除图像.

我们发现了以下错误:

  1. 当我们尝试擦除旋转的图像时,擦除的路径不会反映我们的手指在屏幕上跟踪的路径.

在此输入图像描述

从上图中,黄线是手指的实际移动(在贴纸上垂直向下).但是,发现擦除的路径是对角的.

此问题仅在旋转图像时存在.图像未旋转时不存在.

经过进一步的调试,我们从上述问题中得出一些假设:

  1. 由于旋转图像,x和y绝对位置改变.因此,路径不会通过触摸路径反映正确的路径.

我们怎样才能确保路径仍在参考正确的路径,即使在旋转后手指也会触摸到什么路径?

这是我们在StickerView.java类中扩展ImageView类的代码.

的onTouchEvent

@Override
public boolean onTouchEvent(MotionEvent event) {
    int action = MotionEventCompat.getActionMasked(event);

    float[] pointXY = new float[2];

    pointXY = getAbsolutePosition(event.getX(0),event.getY(0));
    float xPoint = pointXY[0];
    float yPoint = pointXY[1];


    switch (action) {
        case MotionEvent.ACTION_DOWN:

            // first touch
            // if it is inside the image
            if (isInBitmap(event)) {
                // set isInSide to true
                isInSide = true;

                // if it is a scratch
                if(doScratch){
                    // start creating the scratch path
                    mScratchPath = new Path();
                    mScratchPath.moveTo(xPoint, yPoint);
                    mScratchPath.lineTo(xPoint, yPoint);
                    paths.add(new Pair<Path, Paint>(mScratchPath, mScratchCurrentPaint));
                }
            }
            break;
        case MotionEvent.ACTION_MOVE:

            // if two fingers touch and is not a scratch,
            // then it means we can rotate / resize / pan
            if (isPointerDown && !doScratch) {
                // reset matrix
                matrix.reset();
                // get the center point
                scaledImageCenterX = (mImageWidth * mScaleFactor) / 2 ;
                scaledImageCenterY = (mImageHeight * mScaleFactor) / 2;

                // ROTATE THE IMAGE !!!
                matrix.postRotate(lastRotateDegree, scaledImageCenterX, scaledImageCenterY);

                // done to call onDraw
                invalidate();
            }
            break;
    }

    if (operationListener != null) {
        operationListener.onEdit(this);
    }

    // if it is a scratch
    if(doScratch){
        // then for every point, create a scratch path
        mScratchPath.lineTo(xPoint, yPoint);
        invalidate();
    }else{
        mScaleDetector.onTouchEvent(event);
        mRotateDetector.onTouchEvent(event);
        mMoveDetector.onTouchEvent(event);
        mShoveDetector.onTouchEvent(event);
    }
    return handled;
}
Run Code Online (Sandbox Code Playgroud)

的onDraw

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // if the image exists
    if (mBitmap != null) {
        // save canvas
        canvas.save();

        // if it is a scratch
        if(doScratch){
            // scratch the image
            mFillCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

            // Draw our surface, nice an pristine
            final Drawable surface = mScratchSurface;
            if(surface != null) {
                surface.draw(mFillCanvas);
            }
            //Scratch the surface
            if(paths != null) {
                for (Pair<Path, Paint> p : paths) {
                    mFillCanvas.drawPath(p.first,p.second);
                }
            }
            mBitmap = mFillCache;
        }

        canvas.drawBitmap(mBitmap, matrix, bitmapPaint);
        canvas.restore();
    }
}
Run Code Online (Sandbox Code Playgroud)

getAbsolutePosition函数

public float[] getAbsolutePosition(float Ax, float Ay) {
   float[] mMatrixValues = new float[9];
   matrix.getValues(mMatrixValues);

   float x = mImageWidth - ((mMatrixValues[Matrix.MTRANS_X] - Ax) / mMatrixValues[Matrix.MSCALE_X]) - (mImageWidth - getTranslationX());

   float y = mImageHeight - ((mMatrixValues[Matrix.MTRANS_Y] - Ay) / mMatrixValues[Matrix.MSCALE_X]) - (mImageHeight - getTranslationY());

   return new float[] { x, y};
}
Run Code Online (Sandbox Code Playgroud)

Mud*_*med 5

您需要在坐标上应用旋转矩阵。这里theta是图像旋转的角度。 您需要应用矩阵旋转

图片来源维基百科

在代码中它会是这样的

int getAbsoluteX(int x, int y, double theta)
{
   int x_new = (int)(x*Math.cos(theta) - y*Math.sin(theta));
   return x_new;
}

int getAbsoluteY(int x, int y, double theta) 
{
   int y_new = (int)(x*Math.sin(theta) + y*Math.cos(theta));
   return y_new;
}
Run Code Online (Sandbox Code Playgroud)