Android 在下面的类中使用屏幕限制实现Imageview旋转

Android 在下面的类中使用屏幕限制实现Imageview旋转,android,imageview,image-rotation,Android,Imageview,Image Rotation,我正在开发一个android应用程序,用于图像缩放、拖动、旋转到屏幕限制之外。首先,我必须以编程方式使图像适合整个屏幕,并对图像执行缩放、旋转和拖动操作,使其位于屏幕边界之外。我使用了下面的代码,除了旋转功能外,一切都正常运行。我混淆了矩阵计算,所以请帮助任何人如何用这段代码实现旋转特性 Java代码: 导入android.content.Context; 导入android.graphics.Bitmap; 导入android.graphics.Matrix; 导入android.graphi

我正在开发一个android应用程序,用于图像缩放、拖动、旋转到屏幕限制之外。首先,我必须以编程方式使图像适合整个屏幕,并对图像执行缩放、旋转和拖动操作,使其位于屏幕边界之外。我使用了下面的代码,除了旋转功能外,一切都正常运行。我混淆了矩阵计算,所以请帮助任何人如何用这段代码实现旋转特性

Java代码:

导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.Matrix;
导入android.graphics.PointF;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.scalegestruedetector;
导入android.view.view;
导入android.widget.ImageView;
公共类ZoomableImageView扩展了ImageView
{
矩阵=新矩阵();
静态最终int NONE=0;
静态最终整数阻力=1;
静态最终整数缩放=2;
静态最终int CLICK=3;
int模式=无;
PointF last=新的PointF();
PointF start=新的PointF();
浮动最小刻度=1f;
浮点最大刻度=4f;
浮动[]m;
浮点redundantXSpace,redundantYSpace;
浮动宽度、高度;
浮动存储比例=1f;
右浮动、底部、起始宽度、起始高度、bmWidth、bmHeight、bmHeight;
scalegestruedetector mScaleDetector;
语境;
公共ZoomableImageView(上下文、属性集属性)
{
超级(上下文,attr);
super.setClickable(true);
this.context=上下文;
mScaleDetector=新的scalegestruedetector(上下文,新的ScaleListener());
矩阵.setTranslate(1f,1f);
m=新浮点数[9];
setImageMatrix(矩阵);
setScaleType(ScaleType.MATRIX);
setOnTouchListener(新的OnTouchListener()
{
@凌驾
公共布尔onTouch(视图v,运动事件)
{
mScaleDetector.onTouchEvent(事件);
矩阵值(m);
float x=m[矩阵MTRANS_x];
浮点y=m[矩阵MTRANS_y];
PointF curr=新的PointF(event.getX(),event.getY());
开关(event.getAction())
{
//当一个手指接触时
//将模式设置为拖动
case MotionEvent.ACTION\u DOWN:
set(event.getX(),event.getY());
开始。设置(最后);
模式=拖动;
打破
//当两个手指接触时
//将模式设置为缩放
case MotionEvent.ACTION\u指针\u向下:
set(event.getX(),event.getY());
开始。设置(最后);
模式=缩放;
打破
//当手指移动时
//如果模式适用,则移动图像
case MotionEvent.ACTION\u移动:
//如果模式为缩放或
//如果模式为“拖动”且已缩放
如果(模式==缩放| |(模式==拖动和保存比例>最小比例))
{
浮动deltaX=curr.x-last.x;//x差
float deltaY=curr.y-last.y;//y差
float scaleWidth=Math.round(origWidth*saveScale);//应用当前比例后的宽度
float scaleHeight=Math.round(orighight*saveScale);//应用当前比例后的高度
//如果缩放宽度小于视图宽度
//换句话说,如果图像宽度适合视图
//限制左右移动
if(标度宽度<宽度)
{
deltaX=0;
如果(y+deltaY>0)
deltaY=-y;
否则如果(y+deltaY<-底部)
三角洲=-(y+底部);
}
//如果比例高度小于视图高度
//换句话说,如果图像高度与视图相符
//限制上下移动
else if(刻度高度<高度)
{
deltaY=0;
如果(x+deltaX>0)
deltaX=-x;
否则如果(x+deltaX<-右)
deltaX=-(x+右侧);
}
//如果图像的宽度或高度不合适
//限制上下左右
其他的
{
如果(x+deltaX>0)
deltaX=-x;
否则如果(x+deltaX<-右)
deltaX=-(x+右侧);
如果(y+deltaY>0)
deltaY=-y;
否则如果(y+deltaY<-底部)
三角洲=-(y+底部);
}
//使用矩阵移动图像
矩阵。后翻译(deltaX、deltaY);
//将最后一次触摸位置设置为当前位置
最后一组(当前x、当前y);
}
打破
//第一个手指被举起
案例活动。
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

public class ZoomableImageView extends ImageView
{
    Matrix matrix = new Matrix();

    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    static final int CLICK = 3;
    int mode = NONE;

    PointF last = new PointF();
    PointF start = new PointF();
    float minScale = 1f;
    float maxScale = 4f;
    float[] m;

    float redundantXSpace, redundantYSpace;
    float width, height;
    float saveScale = 1f;
    float right, bottom, origWidth, origHeight, bmWidth, bmHeight;

    ScaleGestureDetector mScaleDetector;
    Context context;

    public ZoomableImageView(Context context, AttributeSet attr)
    {
        super(context, attr);
        super.setClickable(true);
        this.context = context;
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
        matrix.setTranslate(1f, 1f);
        m = new float[9];
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);

        setOnTouchListener(new OnTouchListener()
        {

            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                mScaleDetector.onTouchEvent(event);

                matrix.getValues(m);
                float x = m[Matrix.MTRANS_X];
                float y = m[Matrix.MTRANS_Y];
                PointF curr = new PointF(event.getX(), event.getY());

                switch (event.getAction())
                {
                    //when one finger is touching
                    //set the mode to DRAG
                    case MotionEvent.ACTION_DOWN:
                        last.set(event.getX(), event.getY());
                        start.set(last);
                        mode = DRAG;
                        break;
                    //when two fingers are touching
                    //set the mode to ZOOM
                    case MotionEvent.ACTION_POINTER_DOWN:
                        last.set(event.getX(), event.getY());
                        start.set(last);
                        mode = ZOOM;
                        break;
                    //when a finger moves
                    //If mode is applicable move image
                    case MotionEvent.ACTION_MOVE:
                        //if the mode is ZOOM or
                        //if the mode is DRAG and already zoomed
                        if (mode == ZOOM || (mode == DRAG && saveScale > minScale))
                        {
                            float deltaX = curr.x - last.x;// x difference
                            float deltaY = curr.y - last.y;// y difference
                            float scaleWidth = Math.round(origWidth * saveScale);// width after applying current scale
                            float scaleHeight = Math.round(origHeight * saveScale);// height after applying current scale
                            //if scaleWidth is smaller than the views width
                            //in other words if the image width fits in the view
                            //limit left and right movement
                            if (scaleWidth < width)
                            {
                                deltaX = 0;
                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom);
                            }
                            //if scaleHeight is smaller than the views height
                            //in other words if the image height fits in the view
                            //limit up and down movement
                            else if (scaleHeight < height)
                            {
                                deltaY = 0;
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);
                            }
                            //if the image doesnt fit in the width or height
                            //limit both up and down and left and right
                            else
                            {
                                if (x + deltaX > 0)
                                    deltaX = -x;
                                else if (x + deltaX < -right)
                                    deltaX = -(x + right);

                                if (y + deltaY > 0)
                                    deltaY = -y;
                                else if (y + deltaY < -bottom)
                                    deltaY = -(y + bottom);
                            }
                            //move the image with the matrix
                            matrix.postTranslate(deltaX, deltaY);
                            //set the last touch location to the current
                            last.set(curr.x, curr.y);
                        }
                        break;
                    //first finger is lifted
                    case MotionEvent.ACTION_UP:
                        mode = NONE;
                        int xDiff = (int) Math.abs(curr.x - start.x);
                        int yDiff = (int) Math.abs(curr.y - start.y);
                        if (xDiff < CLICK && yDiff < CLICK)
                            performClick();
                        break;
                    // second finger is lifted
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        break;
                }
                setImageMatrix(matrix);
                invalidate();
                return true;
            }

        });
    }

    @Override
    public void setImageBitmap(Bitmap bm)
    {
        super.setImageBitmap(bm);
        bmWidth = bm.getWidth();
        bmHeight = bm.getHeight();
    }

    public void setMaxZoom(float x)
    {
        maxScale = x;
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
    {

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector)
        {
            mode = ZOOM;
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector)
        {
            float mScaleFactor = detector.getScaleFactor();
            float origScale = saveScale;
            saveScale *= mScaleFactor;
            if (saveScale > maxScale)
            {
                saveScale = maxScale;
                mScaleFactor = maxScale / origScale;
            }
            else if (saveScale < minScale)
            {
                saveScale = minScale;
                mScaleFactor = minScale / origScale;
            }
            right = width * saveScale - width - (2 * redundantXSpace * saveScale);
            bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
            if (origWidth * saveScale <= width || origHeight * saveScale <= height)
            {
                matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2);
                if (mScaleFactor < 1)
                {
                    matrix.getValues(m);
                    float x = m[Matrix.MTRANS_X];
                    float y = m[Matrix.MTRANS_Y];
                    if (mScaleFactor < 1)
                    {
                        if (Math.round(origWidth * saveScale) < width)
                        {
                            if (y < -bottom)
                                matrix.postTranslate(0, -(y + bottom));
                            else if (y > 0)
                                matrix.postTranslate(0, -y);
                        }
                        else
                        {
                            if (x < -right)
                                matrix.postTranslate(-(x + right), 0);
                            else if (x > 0)
                                matrix.postTranslate(-x, 0);
                        }
                    }
                }
            }
            else
            {
                matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());
                matrix.getValues(m);
                float x = m[Matrix.MTRANS_X];
                float y = m[Matrix.MTRANS_Y];
                if (mScaleFactor < 1) {
                    if (x < -right)
                        matrix.postTranslate(-(x + right), 0);
                    else if (x > 0)
                        matrix.postTranslate(-x, 0);
                    if (y < -bottom)
                        matrix.postTranslate(0, -(y + bottom));
                    else if (y > 0)
                        matrix.postTranslate(0, -y);
                }
            }
            return true;
        }
    }

    @Override
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        height = MeasureSpec.getSize(heightMeasureSpec);
        //Fit to screen.
        float scale;
        float scaleX =  width / bmWidth;
        float scaleY = height / bmHeight;
        scale = Math.min(scaleX, scaleY);
        matrix.setScale(scale, scale);
        setImageMatrix(matrix);
        saveScale = 1f;

        // Center the image
        redundantYSpace = height - (scale * bmHeight) ;
        redundantXSpace = width - (scale * bmWidth);
        redundantYSpace /= 2;
        redundantXSpace /= 2;

        matrix.postTranslate(redundantXSpace, redundantYSpace);

        origWidth = width - 2 * redundantXSpace;
        origHeight = height - 2 * redundantYSpace;
        right = width * saveScale - width - (2 * redundantXSpace * saveScale);
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale);
        setImageMatrix(matrix);
    }
}
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX);
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);
public void rotateImage(int degrees, Bitmap mBitmap) {
    if (mBitmap != null) {
        Matrix matrix = new Matrix();
        matrix.postRotate(degrees);
        Bitmap bitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, true);
        setImageBitmap(bitmap);

        mDegreesRotated += degrees;
        mDegreesRotated = mDegreesRotated % 360;
    }