Android中利用matrix 控制图片的旋转、缩放、移动

s金晨曦s

s金晨曦s

2016-02-19 09:06

每个人都希望每天都是开心的,不要因为一些琐事扰乱了心情还,闲暇的时间怎么打发,关注图老师可以让你学习更多的好东西,下面为大家推荐Android中利用matrix 控制图片的旋转、缩放、移动,赶紧看过来吧!
本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码:
代码如下:

/**
 * 使用矩阵控制图片移动、缩放、旋转
 */ 
public class CommonImgEffectView extends View { 

    private Context context ; 
    private Bitmap mainBmp , controlBmp ; 
    private int mainBmpWidth , mainBmpHeight , controlBmpWidth , controlBmpHeight ; 
    private Matrix matrix ;  
    private float [] srcPs , dstPs ; 
    private RectF srcRect , dstRect ; 
    private Paint paint ,paintRect , paintFrame; 
    private float deltaX = 0, deltaY = 0; //位移值 
    private float scaleValue = 1; //缩放值 
    private Point lastPoint ; 
    private Point prePivot , lastPivot; 
    private float preDegree , lastDegree ; 
    private short currentSelectedPointindex;        //当前操作点击点 
    private Point symmetricPoint  = new Point();    //当前操作点对称点 

    /**
     * 图片操作类型
     */ 
    public static final int OPER_DEFAULT = -1;      //默认 
    public static final int OPER_TRANSLATE = 0;     //移动 
    public static final int OPER_SCALE = 1;         //缩放 
    public static final int OPER_ROTATE = 2;        //旋转 
    public static final int OPER_SELECTED = 3;      //选择 
    public int lastOper = OPER_DEFAULT; 

    /* 图片控制点
     * 0---1---2
     * |       |
     * 7   8   3
     * |       |
     * 6---5---4 
     */ 
    public static final int CTR_NONE = -1; 
    public static final int CTR_LEFT_TOP = 0; 
    public static final int CTR_MID_TOP = 1; 
    public static final int CTR_RIGHT_TOP = 2; 
    public static final int CTR_RIGHT_MID = 3; 
    public static final int CTR_RIGHT_BOTTOM = 4; 
    public static final int CTR_MID_BOTTOM = 5; 
    public static final int CTR_LEFT_BOTTOM = 6; 
    public static final int CTR_LEFT_MID = 7; 
    public static final int CTR_MID_MID = 8; 
    public int current_ctr = CTR_NONE; 

    public CommonImgEffectView(Context context){ 
        super(context); 
        this.context = context ; 
    } 

    public CommonImgEffectView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        this.context = context ; 
        initData(); 
    } 

    /**
     * 初始化数据
     * @author 张进
     */ 
    private void initData(){ 
        mainBmp = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.flower); 
        controlBmp = BitmapFactory.decodeResource(this.context.getResources(), R.drawable.control); 
        mainBmpWidth = mainBmp.getWidth(); 
        mainBmpHeight = mainBmp.getHeight(); 
        controlBmpWidth = controlBmp.getWidth(); 
        controlBmpHeight = controlBmp.getHeight(); 

        srcPs = new float[]{ 
                                0,0,  
                                mainBmpWidth/2,0,  
                                mainBmpWidth,0,  
                                mainBmpWidth,mainBmpHeight/2, 
                                mainBmpWidth,mainBmpHeight,  
                                mainBmpWidth/2,mainBmpHeight,  
                                0,mainBmpHeight,  
                                0,mainBmpHeight/2,  
                                mainBmpWidth/2,mainBmpHeight/2 
                            }; 
        dstPs = srcPs.clone(); 
        srcRect = new RectF(0, 0, mainBmpWidth, mainBmpHeight); 
        dstRect = new RectF(); 

        matrix = new Matrix(); 

        prePivot = new Point(mainBmpWidth/2, mainBmpHeight/2); 
        lastPivot = new Point(mainBmpWidth/2, mainBmpHeight/2); 

        lastPoint = new Point(0,0); 

        paint = new Paint(); 

        paintRect = new Paint(); 
        paintRect.setColor(Color.RED); 
        paintRect.setAlpha(100); 
        paintRect.setAntiAlias(true); 

        paintFrame = new Paint(); 
        paintFrame.setColor(Color.GREEN); 
        paintFrame.setAntiAlias(true); 

        setMatrix(OPER_DEFAULT); 
    } 

    /**
     * 矩阵变换,达到图形平移的目的
     * @author 张进
     */ 
    private void setMatrix(int operationType){ 
        switch (operationType) { 
        case OPER_TRANSLATE: 
            matrix.postTranslate(deltaX , deltaY); 
            break; 
        case OPER_SCALE: 
            matrix.postScale(scaleValue, scaleValue, symmetricPoint.x, symmetricPoint.y); 
            break; 
        case OPER_ROTATE: 
            matrix.postRotate(preDegree - lastDegree, dstPs[CTR_MID_MID * 2], dstPs[CTR_MID_MID * 2 + 1]); 
            break; 
        } 

        matrix.mapPoints(dstPs, srcPs); 
        matrix.mapRect(dstRect, srcRect); 
    } 

    private boolean isOnPic(int x , int y){ 
        if(dstRect.contains(x, y)){ 
            return true; 
        }else  
            return false; 
    } 

    private int getOperationType(MotionEvent event){ 

        int evX = (int)event.getX(); 
        int evY = (int)event.getY(); 
        int curOper = lastOper; 
        switch(event.getAction()) { 
            case MotionEvent.ACTION_DOWN: 
                current_ctr = isOnCP(evX, evY); 
                Log.i("img", "current_ctr is "+current_ctr); 
                if(current_ctr != CTR_NONE || isOnPic(evX, evY)){ 
                    curOper = OPER_SELECTED; 
                } 
                break; 
            case MotionEvent.ACTION_MOVE: 
                    if(current_ctr CTR_NONE && current_ctr CTR_MID_MID ){ 
                        curOper = OPER_SCALE; 
                    }else if(current_ctr == CTR_MID_MID ){ 
                        curOper = OPER_ROTATE; 
                    }else if(lastOper == OPER_SELECTED){ 
                        curOper = OPER_TRANSLATE; 
                    } 
                break; 
            case MotionEvent.ACTION_UP: 
                curOper = OPER_SELECTED; 
                break; 
            default: 
                break; 
        } 
        Log.d("img", "curOper is "+curOper); 
        return curOper; 

    } 

     /**
     * 判断点所在的控制点
     * @param evX
     * @param evY
     * @return
     */  
    private int isOnCP(int evx, int evy) { 
        Rect rect = new Rect(evx-controlBmpWidth/2,evy-controlBmpHeight/2,evx+controlBmpWidth/2,evy+controlBmpHeight/2); 
        int res = 0 ; 
        for (int i = 0; i dstPs.length; i+=2) { 
            if(rect.contains((int)dstPs[i], (int)dstPs[i+1])){ 
                return res ; 
            } 
            ++res ;  
        } 
        return CTR_NONE; 
    } 

     

    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
        int evX = (int)event.getX(); 
        int evY = (int)event.getY(); 

        int operType = OPER_DEFAULT; 
        operType = getOperationType(event); 

        switch (operType) { 
        case OPER_TRANSLATE: 
            translate(evX, evY); 
            break; 
        case OPER_SCALE: 
            scale(event); 
            break; 
        case OPER_ROTATE: 
            rotate(event); 
            break; 
        } 

        lastPoint.x = evX; 
        lastPoint.y = evY;   

        lastOper = operType; 
        invalidate();//重绘 
        return true; 
    } 

    /**
     * 移动
     * @param evx
     * @param evy
     * @author zhang_jin1
     */ 
    private void translate(int evx , int evy){ 

        prePivot.x += evx - lastPoint.x; 
        prePivot.y += evy -lastPoint.y; 

        deltaX = prePivot.x - lastPivot.x; 
        deltaY = prePivot.y - lastPivot.y; 

        lastPivot.x = prePivot.x; 
        lastPivot.y = prePivot.y; 

        setMatrix(OPER_TRANSLATE); //设置矩阵 

    } 

    /**
     * 缩放
     * 0---1---2
     * |       |
     * 7   8   3
     * |       |
     * 6---5---4
     * @param evX
     * @param evY
     */ 
    private void scale(MotionEvent event) { 

        int pointIndex = current_ctr*2 ; 

        float px = dstPs[pointIndex]; 
        float py = dstPs[pointIndex+1]; 

        float evx = event.getX(); 
        float evy = event.getY(); 

        float oppositeX = 0 ; 
        float oppositeY = 0 ; 
        if(current_ctr4 && current_ctr = 0){ 
             oppositeX = dstPs[pointIndex+8]; 
             oppositeY = dstPs[pointIndex+9]; 
        }else if(current_ctr = 4){ 
             oppositeX = dstPs[pointIndex-8]; 
             oppositeY = dstPs[pointIndex-7]; 
        } 
        float temp1 = getDistanceOfTwoPoints(px,py,oppositeX,oppositeY); 
        float temp2 = getDistanceOfTwoPoints(evx,evy,oppositeX,oppositeY); 

        this.scaleValue = temp2 / temp1 ; 
        symmetricPoint.x = (int) oppositeX; 
        symmetricPoint.y = (int)oppositeY; 

        Log.i("img", "scaleValue is "+scaleValue); 
        setMatrix(OPER_SCALE); 
    } 

    /**
     * 旋转图片
     * 0---1---2
     * |       |
     * 7   8   3
     * |       |
     * 6---5---4 
     * @param evX
     * @param evY
     */ 
    private void rotate(MotionEvent event) { 

        if(event.getPointerCount() == 2){ 
            preDegree = computeDegree(new Point((int)event.getX(0), (int)event.getY(0)), new Point((int)event.getX(1), (int)event.getY(1))); 
        }else{ 
            preDegree = computeDegree(new Point((int)event.getX(), (int)event.getY()), new Point((int)dstPs[16], (int)dstPs[17])); 
        } 
        setMatrix(OPER_ROTATE); 
        lastDegree = preDegree; 
    } 

     
    /**
     * 计算两点与垂直方向夹角
     * @param p1
     * @param p2
     * @return
     */ 
    public float computeDegree(Point p1, Point p2){ 
        float tran_x = p1.x - p2.x; 
        float tran_y = p1.y - p2.y; 
        float degree = 0.0f; 
        float angle = (float)(Math.asin(tran_x/Math.sqrt(tran_x*tran_x + tran_y* tran_y))*180/Math.PI); 
        if(!Float.isNaN(angle)){ 
            if(tran_x = 0 && tran_y = 0){//第一象限 
                degree = angle; 
            }else if(tran_x = 0 && tran_y = 0){//第二象限 
                degree = angle; 
            }else if(tran_x = 0 && tran_y = 0){//第三象限 
                degree = -180 - angle; 
            }else if(tran_x = 0 && tran_y = 0){//第四象限 
                degree = 180 - angle; 
            } 
        } 
        return degree; 
    } 

    /**
     * 计算两个点之间的距离
     * @param p1
     * @param p2
     * @return
     */ 
    private float getDistanceOfTwoPoints(Point p1, Point p2){ 
        return (float)(Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))); 
    } 

    private float getDistanceOfTwoPoints(float x1,float y1,float x2,float y2){ 
        return (float)(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))); 
    } 

     
    @Override 
    public void onDraw(Canvas canvas){ 
        drawBackground(canvas);//绘制背景,以便测试矩形的映射 
        canvas.drawBitmap(mainBmp, matrix, paint);//绘制主图片 
        drawFrame(canvas);//绘制边框,以便测试点的映射 
        drawControlPoints(canvas);//绘制控制点图片 
    } 

    private void drawBackground(Canvas canvas){ 
        canvas.drawRect(dstRect, paintRect); 
    } 

    private void drawFrame(Canvas canvas){ 
        canvas.drawLine(dstPs[0], dstPs[1], dstPs[4], dstPs[5], paintFrame); 
        canvas.drawLine(dstPs[4], dstPs[5], dstPs[8], dstPs[9], paintFrame); 
        canvas.drawLine(dstPs[8], dstPs[9], dstPs[12], dstPs[13], paintFrame); 
        canvas.drawLine(dstPs[0], dstPs[1], dstPs[12], dstPs[13], paintFrame); 
        canvas.drawPoint(dstPs[16], dstPs[17], paintFrame); 
    } 

    private void drawControlPoints(Canvas canvas){ 

        for (int i = 0; i dstPs.length; i+=2) { 
            canvas.drawBitmap(controlBmp, dstPs[i]-controlBmpWidth/2, dstPs[i+1]-controlBmpHeight/2, paint); 
        } 

    } 



Demo效果:

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

展开更多 50%)
分享

猜你喜欢

Android中利用matrix 控制图片的旋转、缩放、移动

编程语言 网络编程
Android中利用matrix 控制图片的旋转、缩放、移动

CSS控制图片成比例缩放

Web开发
CSS控制图片成比例缩放

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Android 图片缩放与旋转的实现详解

编程语言 网络编程
Android 图片缩放与旋转的实现详解

如何利用Photoshop移动和缩放

软件教程
如何利用Photoshop移动和缩放

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

CSS样式控制图片裁切显示

Web开发
CSS样式控制图片裁切显示

ImageFlow可鼠标控制图片滚动

Web开发
ImageFlow可鼠标控制图片滚动

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

在Android模拟器上模拟GPS功能总是null的解决方法

在Android模拟器上模拟GPS功能总是null的解决方法

WPS文字支持新版word公式吗

WPS文字支持新版word公式吗
下拉加载更多内容 ↓