织梦CMS - 轻松建站从此开始!

罗索实验室

当前位置: 主页 > 嵌入式开发 > Android >

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

落鹤生 发布于 2012-03-27 10:54 点击:次 
本文主要讲解利用android中Matrix控制图形的旋转缩放移动,使用矩阵控制图片移动、缩放、旋转
TAG:

本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码:

  1. /**  
  2.  * 使用矩阵控制图片移动、缩放、旋转  
  3.  * @author 张进  
  4.  */   
  5. public class CommonImgEffectView extends View {
  6.     private Context context ;
  7.     private Bitmap mainBmp , controlBmp ;
  8.     private int mainBmpWidth, mainBmpHeight, controlBmpWidth, controlBmpHeight ;
  9.     private Matrix matrix ;
  10.     private float [] srcPs , dstPs ;
  11.     private RectF srcRect , dstRect ;
  12.     private Paint paint ,paintRect , paintFrame;
  13.     private float deltaX = 0, deltaY = 0//位移值
  14.     private float scaleValue = 1//缩放值
  15.     private Point lastPoint ;
  16.     private Point prePivot , lastPivot;
  17.     private float preDegree , lastDegree ;
  18.     private short currentSelectedPointindex;        //当前操作点击点
  19.     private Point symmetricPoint  = new Point();    //当前操作点对称点

  20.     /**  
  21.      * 图片操作类型  
  22.      */   
  23.     public static final int OPER_DEFAULT = -1;      //默认   
  24.     public static final int OPER_TRANSLATE = 0;     //移动   
  25.     public static final int OPER_SCALE = 1;         //缩放   
  26.     public static final int OPER_ROTATE = 2;        //旋转   
  27.     public static final int OPER_SELECTED = 3;      //选择   
  28.     public int lastOper = OPER_DEFAULT;   
  29.        
  30.     /* 图片控制点  
  31.      * 0---1---2  
  32.      * |       |  
  33.      * 7   8   3  
  34.      * |       |  
  35.      * 6---5---4   
  36.      */   
  37.     public static final int CTR_NONE = -1;   
  38.     public static final int CTR_LEFT_TOP = 0;   
  39.     public static final int CTR_MID_TOP = 1;   
  40.     public static final int CTR_RIGHT_TOP = 2;   
  41.     public static final int CTR_RIGHT_MID = 3;   
  42.     public static final int CTR_RIGHT_BOTTOM = 4;   
  43.     public static final int CTR_MID_BOTTOM = 5;   
  44.     public static final int CTR_LEFT_BOTTOM = 6;   
  45.     public static final int CTR_LEFT_MID = 7;   
  46.     public static final int CTR_MID_MID = 8;   
  47.     public int current_ctr = CTR_NONE;   
  48.        
  49.     public CommonImgEffectView(Context context){   
  50.         super(context);   
  51.         this.context = context ;   
  52.     }   
  53.        
  54.     public CommonImgEffectView(Context context, AttributeSet attrs) {   
  55.         super(context, attrs);   
  56.         this.context = context ;   
  57.         initData();   
  58.     }   
  59.        
  60.     /**  
  61.      * 初始化数据  
  62.      * @author 张进  
  63.      */   
  64.     private void initData(){   
  65.         mainBmp = BitmapFactory.decodeResource(this.context.getResources()
  66. , R.drawable.flower);   
  67.         controlBmp = BitmapFactory.decodeResource(this.context.getResources()
  68. , R.drawable.control);   
  69.         mainBmpWidth = mainBmp.getWidth();   
  70.         mainBmpHeight = mainBmp.getHeight();   
  71.         controlBmpWidth = controlBmp.getWidth();   
  72.         controlBmpHeight = controlBmp.getHeight();   
  73.            
  74.         srcPs = new float[]{   
  75.                                 0,0,    
  76.                                 mainBmpWidth/2,0,    
  77.                                 mainBmpWidth,0,    
  78.                                 mainBmpWidth,mainBmpHeight/2,   
  79.                                 mainBmpWidth,mainBmpHeight,    
  80.                                 mainBmpWidth/2,mainBmpHeight,    
  81.                                 0,mainBmpHeight,    
  82.                                 0,mainBmpHeight/2,    
  83.                                 mainBmpWidth/2,mainBmpHeight/2   
  84.                             };   
  85.         dstPs = srcPs.clone();   
  86.         srcRect = new RectF(00, mainBmpWidth, mainBmpHeight);   
  87.         dstRect = new RectF();   
  88.            
  89.         matrix = new Matrix();   
  90.            
  91.         prePivot = new Point(mainBmpWidth/2, mainBmpHeight/2);   
  92.         lastPivot = new Point(mainBmpWidth/2, mainBmpHeight/2);   
  93.            
  94.         lastPoint = new Point(0,0);   
  95.            
  96.         paint = new Paint();   
  97.            
  98.         paintRect = new Paint();   
  99.         paintRect.setColor(Color.RED);   
  100.         paintRect.setAlpha(100);   
  101.         paintRect.setAntiAlias(true);   
  102.            
  103.         paintFrame = new Paint();   
  104.         paintFrame.setColor(Color.GREEN);   
  105.         paintFrame.setAntiAlias(true);   
  106.            
  107.         setMatrix(OPER_DEFAULT);   
  108.     }   
  109.        
  110.     /**  
  111.      * 矩阵变换,达到图形平移的目的  
  112.      * @author 张进  
  113.      */   
  114.     private void setMatrix(int operationType){   
  115.         switch (operationType) {   
  116.         case OPER_TRANSLATE:   
  117.             matrix.postTranslate(deltaX , deltaY);   
  118.             break;   
  119.         case OPER_SCALE:   
  120.             matrix.postScale(scaleValue, scaleValue, symmetricPoint.x
  121. , symmetricPoint.y);   
  122.             break;   
  123.         case OPER_ROTATE:   
  124.             matrix.postRotate(preDegree - lastDegree, dstPs[CTR_MID_MID * 2]
  125. , dstPs[CTR_MID_MID * 2 + 1]);   
  126.             break;   
  127.         }   
  128.            
  129.         matrix.mapPoints(dstPs, srcPs);   
  130.         matrix.mapRect(dstRect, srcRect);   
  131.     }   
  132.        
  133.     private boolean isOnPic(int x , int y){   
  134.         if(dstRect.contains(x, y)){   
  135.             return true;   
  136.         }else    
  137.             return false;   
  138.     }   
  139.        
  140.     private int getOperationType(MotionEvent event){   
  141.    
  142.         int evX = (int)event.getX();   
  143.         int evY = (int)event.getY();   
  144.         int curOper = lastOper;   
  145.         switch(event.getAction()) {   
  146.             case MotionEvent.ACTION_DOWN:   
  147.                 current_ctr = isOnCP(evX, evY);   
  148.                 Log.i("img""current_ctr is "+current_ctr);   
  149.                 if(current_ctr != CTR_NONE || isOnPic(evX, evY)){   
  150.                     curOper = OPER_SELECTED;   
  151.                 }   
  152.                 break;   
  153.             case MotionEvent.ACTION_MOVE:   
  154.                     if(current_ctr > CTR_NONE && current_ctr < CTR_MID_MID ){   
  155.                         curOper = OPER_SCALE;   
  156.                     }else if(current_ctr == CTR_MID_MID ){   
  157.                         curOper = OPER_ROTATE;   
  158.                     }else if(lastOper == OPER_SELECTED){   
  159.                         curOper = OPER_TRANSLATE;   
  160.                     }   
  161.                 break;   
  162.             case MotionEvent.ACTION_UP:   
  163.                 curOper = OPER_SELECTED;   
  164.                 break;   
  165.             default:   
  166.                 break;   
  167.         }   
  168.         Log.d("img""curOper is "+curOper);   
  169.         return curOper;   
  170.            
  171.     }   
  172.        
  173.      /**  
  174.      * 判断点所在的控制点  
  175.      * @param evX  
  176.      * @param evY  
  177.      * @return  
  178.      */    
  179.     private int isOnCP(int evx, int evy) {   
  180.         Rect rect = new Rect(evx-controlBmpWidth/2,evy-controlBmpHeight/2
  181. ,evx+controlBmpWidth/2,evy+controlBmpHeight/2);   
  182.         int res = 0 ;   
  183.         for (int i = 0; i < dstPs.length; i+=2) {   
  184.             if(rect.contains((int)dstPs[i], (int)dstPs[i+1])){   
  185.                 return res ;   
  186.             }   
  187.             ++res ;    
  188.         }   
  189.         return CTR_NONE;   
  190.     }   
  191.        
  192.        
  193.        
  194.     @Override   
  195.     public boolean dispatchTouchEvent(MotionEvent event) {   
  196.         int evX = (int)event.getX();   
  197.         int evY = (int)event.getY();   
  198.            
  199.         int operType = OPER_DEFAULT;   
  200.         operType = getOperationType(event);   
  201.            
  202.         switch (operType) {   
  203.         case OPER_TRANSLATE:   
  204.             translate(evX, evY);   
  205.             break;   
  206.         case OPER_SCALE:   
  207.             scale(event);   
  208.             break;   
  209.         case OPER_ROTATE:   
  210.             rotate(event);   
  211.             break;   
  212.         }   
  213.        
  214.         lastPoint.x = evX;   
  215.         lastPoint.y = evY;     
  216.            
  217.         lastOper = operType;   
  218.         invalidate();//重绘   
  219.         return true;   
  220.     }   
  221.    
  222.     /**  
  223.      * 移动  
  224.      * @param evx  
  225.      * @param evy  
  226.      * @author zhang_jin1  
  227.      */   
  228.     private void translate(int evx , int evy){   
  229.            
  230.         prePivot.x += evx - lastPoint.x;   
  231.         prePivot.y += evy -lastPoint.y;   
  232.            
  233.         deltaX = prePivot.x - lastPivot.x;   
  234.         deltaY = prePivot.y - lastPivot.y;   
  235.            
  236.         lastPivot.x = prePivot.x;   
  237.         lastPivot.y = prePivot.y;   
  238.            
  239.         setMatrix(OPER_TRANSLATE); //设置矩阵   
  240.            
  241.     }   
  242.        
  243.     /**  
  244.      * 缩放  
  245.      * 0---1---2  
  246.      * |       |  
  247.      * 7   8   3  
  248.      * |       |  
  249.      * 6---5---4  
  250.      * @param evX  
  251.      * @param evY  
  252.      */   
  253.     private void scale(MotionEvent event) {   
  254.            
  255.         int pointIndex = current_ctr*2 ;   
  256.            
  257.         float px = dstPs[pointIndex];   
  258.         float py = dstPs[pointIndex+1];   
  259.            
  260.         float evx = event.getX();   
  261.         float evy = event.getY();   
  262.            
  263.         float oppositeX = 0 ;   
  264.         float oppositeY = 0 ;   
  265.         if(current_ctr<4 && current_ctr >= 0){   
  266.              oppositeX = dstPs[pointIndex+8];   
  267.              oppositeY = dstPs[pointIndex+9];   
  268.         }else if(current_ctr >= 4){   
  269.              oppositeX = dstPs[pointIndex-8];   
  270.              oppositeY = dstPs[pointIndex-7];   
  271.         }   
  272.         float temp1 = getDistanceOfTwoPoints(px,py,oppositeX,oppositeY);   
  273.         float temp2 = getDistanceOfTwoPoints(evx,evy,oppositeX,oppositeY);   
  274.            
  275.         this.scaleValue = temp2 / temp1 ;   
  276.         symmetricPoint.x = (int) oppositeX;   
  277.         symmetricPoint.y = (int)oppositeY;   
  278.            
  279.         Log.i("img""scaleValue is "+scaleValue);   
  280.         setMatrix(OPER_SCALE);   
  281.     }   
  282.        
  283.     /**  
  284.      * 旋转图片  
  285.      * 0---1---2  
  286.      * |       |  
  287.      * 7   8   3  
  288.      * |       |  
  289.      * 6---5---4   
  290.      * @param evX  
  291.      * @param evY  
  292.      */   
  293.     private void rotate(MotionEvent event) {   
  294.           
  295.         if(event.getPointerCount() == 2){   
  296.             preDegree = computeDegree(new Point((int)event.getX(0)
  297. , (int)event.getY(0)), new Point((int)event.getX(1), (int)event.getY(1)));   
  298.         }else{   
  299.             preDegree = computeDegree(new Point((int)event.getX()
  300. , (int)event.getY()), new Point((int)dstPs[16], (int)dstPs[17]));   
  301.         }   
  302.         setMatrix(OPER_ROTATE);   
  303.         lastDegree = preDegree;   
  304.     }   
  305.        
  306.        
  307.     /**  
  308.      * 计算两点与垂直方向夹角  
  309.      * @param p1  
  310.      * @param p2  
  311.      * @return  
  312.      */   
  313.     public float computeDegree(Point p1, Point p2){   
  314.         float tran_x = p1.x - p2.x;   
  315.         float tran_y = p1.y - p2.y;   
  316.         float degree = 0.0f;   
  317.         float angle = (float)(Math.asin(tran_x/Math.sqrt(tran_x*tran_x
  318.  + tran_y* tran_y))*180/Math.PI);   
  319.         if(!Float.isNaN(angle)){   
  320.             if(tran_x >= 0 && tran_y <= 0){//第一象限   
  321.                 degree = angle;   
  322.             }else if(tran_x <= 0 && tran_y <= 0){//第二象限   
  323.                 degree = angle;   
  324.             }else if(tran_x <= 0 && tran_y >= 0){//第三象限   
  325.                 degree = -180 - angle;   
  326.             }else if(tran_x >= 0 && tran_y >= 0){//第四象限   
  327.                 degree = 180 - angle;   
  328.             }   
  329.         }   
  330.         return degree;   
  331.     }   
  332.        
  333.     /**  
  334.      * 计算两个点之间的距离  
  335.      * @param p1  
  336.      * @param p2  
  337.      * @return  
  338.      */   
  339.     private float getDistanceOfTwoPoints(Point p1, Point p2){   
  340.         return (float)(Math.sqrt((p1.x - p2.x) * (p1.x - p2.x)
  341.  + (p1.y - p2.y) * (p1.y - p2.y)));   
  342.     }   
  343.        
  344.     private float getDistanceOfTwoPoints(float x1,float y1,float x2,float y2){   
  345.         return (float)(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)));   
  346.     }   
  347.        
  348.        
  349.     @Override   
  350.     public void onDraw(Canvas canvas){   
  351.         drawBackground(canvas);//绘制背景,以便测试矩形的映射   
  352.         canvas.drawBitmap(mainBmp, matrix, paint);//绘制主图片   
  353.         drawFrame(canvas);//绘制边框,以便测试点的映射   
  354.         drawControlPoints(canvas);//绘制控制点图片   
  355.     }   
  356.        
  357.     private void drawBackground(Canvas canvas){   
  358.         canvas.drawRect(dstRect, paintRect);   
  359.     }   
  360.        
  361.     private void drawFrame(Canvas canvas){   
  362.         canvas.drawLine(dstPs[0], dstPs[1], dstPs[4], dstPs[5], paintFrame);   
  363.         canvas.drawLine(dstPs[4], dstPs[5], dstPs[8], dstPs[9], paintFrame);   
  364.         canvas.drawLine(dstPs[8], dstPs[9], dstPs[12], dstPs[13], paintFrame);   
  365.         canvas.drawLine(dstPs[0], dstPs[1], dstPs[12], dstPs[13], paintFrame);   
  366.         canvas.drawPoint(dstPs[16], dstPs[17], paintFrame);   
  367.     }   
  368.        
  369.     private void drawControlPoints(Canvas canvas){   
  370.            
  371.         for (int i = 0; i < dstPs.length; i+=2) {   
  372.             canvas.drawBitmap(controlBmp, dstPs[i]-controlBmpWidth/2
  373. , dstPs[i+1]-controlBmpHeight/2, paint);   
  374.         }   
  375.            
  376.     }   
  377.        
  378. }   

Demo效果:

(zj_1395201)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www1.rosoo.net/a/201203/15877.html]
本文出处:CSDN博客 作者:zj_1395201 原文
顶一下
(18)
100%
踩一下
(0)
0%
------分隔线----------------------------
相关文章
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容