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

/** * 使用矩阵控制图片移动、缩放、旋转 * @author 张进 */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 ;        initData();    }        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_ctr<4 && 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效果:




更多相关文章

  1. Android中dispatchDraw分析
  2. 锁屏界面
  3. android WebView 图片缩放功能小结
  4. android OpenGL ES2.0编程初学
  5. android和j2me之清屏(clearScreen)
  6. [置顶] android 图标的绘制
  7. android和j2me之清屏(clearScreen)
  8. Android绘制简单折线图的步骤
  9. android使用inSampleSize、inScaled、inDensity、inTargetDensit

随机推荐

  1. Android系统在超级终端下必会的命令大全(a
  2. Android圆角图片
  3. Android(安卓)XML解析
  4. Android(安卓)之EditText自动弹出/不弹出
  5. Android控件属性大全
  6. android相对布局的案例
  7. Android(安卓)studio教程学习笔记4——Te
  8. 详解 Android(安卓)的 Activity 组件
  9. 如何通过代码更改ANDROID的UI布局
  10. Android之ListView中的分割线