如何在Android中旋转、缩放和移动图像

如何在Android中旋转、缩放和移动图像,android,image-rotation,zooming,custom-view,Android,Image Rotation,Zooming,Custom View,我是ANDROID新手,希望在自己的自定义视图中旋转、缩放和移动图像。但我用相同的onTouchEvent方法编写了所有这些(旋转、缩放、移动)。所以当我移动图像时,它也会旋转,或者我缩放图像时,它会移动。我必须分开处理,但不知道如何处理。我想我可以添加一个按钮,例如,它的名称是“旋转”。所以我可以修复图像,它只允许旋转。但我无法在自定义视图中创建按钮。代码如下所示: 公共类MyView扩展了视图{ //当前正在移动对象的是“活动指针”。 private int mActivePointerI

我是ANDROID新手,希望在自己的自定义视图中旋转、缩放和移动图像。但我用相同的onTouchEvent方法编写了所有这些(旋转、缩放、移动)。所以当我移动图像时,它也会旋转,或者我缩放图像时,它会移动。我必须分开处理,但不知道如何处理。我想我可以添加一个按钮,例如,它的名称是“旋转”。所以我可以修复图像,它只允许旋转。但我无法在自定义视图中创建按钮。代码如下所示:

公共类MyView扩展了视图{

//当前正在移动对象的是“活动指针”。
private int mActivePointerId=无效的\u指针\u ID;
私有静态final int无效\u指针\u ID=-1;
专用scalegestruedetector mScaleDetector;
私人浮动mScaleFactor=1.f;
私人浮动mPosX;
私家车;
私有浮动mLastTouchX;
私密的浮躁和敏感;
//用于获取图像
私有位图bmp;
私有可绘制图像;
专用字节[]字节数组;
private ByteArrayBuffer baf=null;
//轮换
int方向=0;
整数度=0;
私人浮动中心;
私人浮动中心;
私有浮动纽交所;
私人花车;
私人浮动轮换;
私人浮动轮换;
公共MyView(上下文){
这个(上下文,null,0);
}
公共MyView(上下文、属性集属性){
这(上下文,属性,0);
}
公共MyView(上下文上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
字符串url=”http://www.queness.com/resources/images/png/apple_ex.png";    
AsyncTask连接=新建GetUrlData().execute(url);
试一试{
baf=connection.get();
}捕捉(中断异常e){
e、 printStackTrace();
}捕获(执行例外){
e、 printStackTrace();
}
byteArray=baf.toByteArray();
bmp=BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
image=新的BitmapDrawable(context.getResources(),bmp);
setBounds(0,0,image.getIntrinsicWidth(),image.getIntrinsicHeight());
mScaleDetector=新的scalegestruedetector(上下文,新的ScaleListener());
}
@凌驾
受保护的void onDraw(画布){
super.onDraw(帆布);
画布。drawColor(颜色。黑色);
//轮换
int height=this.getHeight();
int width=this.getWidth();
centerX=宽度/2;
中心Y=高度/2;
画布。旋转(方向、宽度/2、高度/2);
canvas.save();
canvas.translate(mPosX,mPosY);
canvas.scale(mScaleFactor,mScaleFactor);
图像绘制(画布);
canvas.restore();
}
//轮换
私有void updateRotation(float newX2,float newY2){
度数=(int)数学到度数(Math.atan2(newY,newX))-90;
方向(度);
}
//轮换
公共方向(内部方向){
这个方向=方向;
这个。使无效();
}
@凌驾
公共布尔onTouchEvent(运动事件){
//让scalegestruedetector检查所有事件。
mScaleDetector.onTouchEvent(事件);
final int action=event.getAction();
if(action==MotionEvent.action\u DOWN){
最终浮点x=event.getX();
最终浮点y=event.getY();
mLastTouchX=x;
mLastTouchY=y;
MacTivePointId=event.getPointerId(0);
}
if(action==MotionEvent.action\u MOVE){
final int pointerIndex=event.findPointerIndex(MacTivePointInterId);
最终浮点x=event.getX(pointerIndex);
最终浮点y=event.getY(pointerIndex);
//仅在ScaleGetureDetector未处理手势时移动。
如果(!mScaleDetector.isInProgress()){
最终浮点数dx=x-mLastTouchX;
最终浮子dy=y—最大浮子厚度;
mPosX+=dx;
mPosY+=dy;
使无效();
}
mLastTouchX=x;
mLastTouchY=y;
//轮换
rotateX=event.getX();
rotateY=event.getY();
newX=centerX rotateX;
newY=中心旋转;
更新操作(newX,newY);
}
if(action==MotionEvent.action\u UP){
MacTivePointId=无效的\u指针\u ID;
更新操作(newX,newY);
}
if(action==MotionEvent.action\u CANCEL){
MacTivePointId=无效的\u指针\u ID;
}
if(action==MotionEvent.action\u指针\u向上){
final int pointerIndex=(event.getAction()&MotionEvent.ACTION\u指针\u索引\u掩码)
>>MotionEvent.ACTION\u指针\u索引\u移位;
final int pointerId=event.getPointerId(pointerIndex);
if(pointerId==MacTivePointId){
//这是我们的活动指针上升。请选择一个新指针
//激活指针并进行相应调整。
final int newPointerIndex=pointerIndex==0?1:0;
mLastTouchX=event.getX(newPointerIndex);
mLastTouchY=event.getY(newPointerIndex);
MacTivePointId=event.getPointerId(newPointerIndex);
}
}
返回true;
}
私有类ScaleListener扩展了scalegestruedetector.SimpleOnScalegestrueListener{
@凌驾
公共布尔标度(scalegestruedetector检测器){
mScaleFactor*=detector.getScaleFactor();
//不要让对象变得太小或太大。
mScaleFactor=数学最大值(0.1f,数学最小值(mScaleFactor,5.0f));
使无效();
返回true;
}
}
}


我希望我能说出我想要什么。你能帮我解决这个问题吗?

试试下面的代码,它对我有用

float[] lastEvent = null;
float d = 0f;
float newRot = 0f;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
public static String fileNAME;
public static int framePos = 0;

private float scale = 0;
private float newDist = 0;

// Fields
private String TAG = this.getClass().getSimpleName();

// We can be in one of these 3 states
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;

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

 public boolean onTouch(View v, MotionEvent event) {
            ImageView view = (ImageView) v;

            // Handle touch events here...
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                lastEvent = null;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    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_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                lastEvent = null;
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    // ...
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x, event.getY()
                            - start.y);
                } else if (mode == ZOOM && event.getPointerCount() == 2) {
                    float newDist = spacing(event);
                    matrix.set(savedMatrix);
                    if (newDist > 10f) {
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                    if (lastEvent != null) {
                        newRot = rotation(event);
                        float r = newRot - d;
                        matrix.postRotate(r, view.getMeasuredWidth() / 2,
                                view.getMeasuredHeight() / 2);
                    }
                }
                break;
            }

            view.setImageMatrix(matrix);

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

    return (float) Math.toDegrees(radians);
}
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);
    }

理解所有的概念,把所有的代码写在一起,我建议你理解,不要复制粘贴看看这个@ThiruVT你的评论完全正确。我复制粘贴了我的代码,并意识到我对我的问题一无所知。但在那之后,我搜索并理解了所有的内容,并独自处理了我的问题。所以谢谢你的建议。@PadmaKumar也谢谢你对sharin的帮助
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);

    return (float) Math.toDegrees(radians);
}
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);
    }