0

所以我一直在尝试创建一个可以拖动、缩放和旋转照片的程序。我似乎遇到的一个大问题是,每当我尝试旋转照片时,它都会沿着角落旋转,而不是围绕中心旋转。这意味着当我尝试旋转图像时,它很快就会离开我的手指。

我遇到的另一个大问题是,每次我用两根手指触摸时,图像都会重置为完全直立,而不是我触摸它时的角度。

@Override
protected void onDraw(Canvas canvas) {


    canvas.save();
    //if(mode==DRAG)
    canvas.translate(mPosX, mPosY);
    if (myScale.isInProgress()) {
        canvas.scale(mScaleFactor, mScaleFactor, myScale.getFocusX(), myScale.getFocusY());
    }
    else{
        canvas.scale(mScaleFactor, mScaleFactor, mLastGestureX, mLastGestureY);
    }

    if (myScale.isInProgress()) {
        canvas.rotate(degrees, myScale.getFocusX(), myScale.getFocusY());
    }
    else{
        canvas.rotate(degrees, mLastGestureX, mLastGestureY);
    }
    //canvas.setMatrix(matrix);
    //setImageMatrix(matrix);
    super.onDraw(canvas);
    canvas.restore();
    //canvas.drawBitmap(,matrix,new Paint());
}













@Override
public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);
    if(event.getPointerCount()>1){

        myScale.onTouchEvent(event);
    }
    switch (event.getAction() & MotionEvent.ACTION_MASK){
            case MotionEvent.ACTION_DOWN: {
                savedMatrix.set(matrix);

                final float x = event.getX();
                final float y = event.getY();
                mode=DRAG;
                // Remember where we started
                mLastTouchX = x;
                mLastTouchY = y;
                mActivePointerId = event.getPointerId(0);
                lastEvent = null;
                break;
            }
        case MotionEvent.ACTION_POINTER_DOWN: {
            oldDist = spacing(event);
            //savedMatrix.set(matrix);
            //midPoint(mid, event);
            Log.d("touchResponse: ", "mode=ZOOM");
            final float gx = myScale.getFocusX();
            final float gy = myScale.getFocusY();
            mLastGestureX=gx;
            mLastGestureY=gy;
            mode=ZOOM;
            lastEvent = new float[4];
            lastEvent[0] = event.getX(0);
            lastEvent[1] = event.getX(1);
            lastEvent[2] = event.getY(0);
            lastEvent[3] = event.getY(1);
            d = rotation(event);
            break;
        }


            case MotionEvent.ACTION_MOVE: {
                final int pointerIndex = event.findPointerIndex(mActivePointerId);
                final float x = event.getX(pointerIndex);
                final float y = event.getY(pointerIndex);


                // Calculate the distance moved

            if(!myScale.isInProgress()&&mode==DRAG){
                    // Move the object
                float dx = x-mLastTouchX;
                float dy = y-mLastTouchY;
                    mPosX+=dx;
                     mPosY+=dy;


                    // Remember this touch position for the next move event


                    // Invalidate to request a redraw
                    invalidate();

            }
                mLastTouchX = x;
                mLastTouchY = y;
                if(event.getPointerCount()==2){
                    if (lastEvent!=null){
                    newRot=rotation(event);
                    degrees = newRot-d;

                    }

                }
                invalidate();
                break;

            }

        case MotionEvent.ACTION_UP: {

        }


        case MotionEvent.ACTION_POINTER_UP: {
            // Extract the index of the pointer that left the touch sensor\
            mode=NONE;
            mode = NONE;
            lastEvent = null;
            final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            final int pointerId = event.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 = event.getX(newPointerIndex);
                mLastTouchY = event.getY(newPointerIndex);
                mActivePointerId = event.getPointerId(newPointerIndex);
            }
            invalidate();

            break;
        }

        }

    return true;
}
















//this is a method i ripped from a tutoriaql
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);
}



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);
}

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

        mScaleFactor *= detector.getScaleFactor();

        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f));


        //matrix=temp;

        invalidate();
        return true;
    }
}

private float rotation(MotionEvent event) {
    double delta_x = (event.getX(0) - event.getX(1));
    double delta_y = (event.getY(0) - event.getY(1));
    double radians = Math.atan2(delta_y, delta_x);
    //if (Constant.TRACE) Log.d("Rotation ~~~~~~~~~~~~~~~~~", delta_x+" ## "+delta_y+" ## "+radians+" ## "
    //        +Math.toDegrees(radians));
    Log.d("Rotation ~~~~~~~~~~~~~~~~~", delta_x+" ## "+delta_y+" ## "+radians+" ## "
            +Math.toDegrees(radians));
    return (float) Math.toDegrees(radians);
}
4

1 回答 1

0

如果要绕中心旋转,则需要先平移到中心。这会将新原点设置为图像的中心,并且旋转始终围绕原点旋转。

于 2013-05-19T04:32:02.177 回答