本文主要讲解利用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 ; } 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中保存Bitmap图片到指定文件夹中的方法
  2. picasso框架的使用
  3. Android系统自带分享
  4. Android-Fresco系列6 图片解码
  5. Android(安卓)获取图片研究
  6. Android的图片压缩并上传
  7. android > ListView > 加载 网络/assets图片
  8. Android中图片的处理(放大缩小,去色,转换格式,增加水印等)
  9. android 缓存Bitmap - 开发文档翻译

随机推荐

  1. Android电源管理
  2. android架构
  3. Android(安卓)版本兼容适配
  4. Android即时通讯和sns开源项目汇总
  5. Android(安卓)mediaplayer 播放本地音乐
  6. android菜单学习笔记
  7. Android属性动画源码分析(四)
  8. Android(安卓)上实现水波特效二--优化
  9. Android: AIDL --- Android中的远程接口
  10. android 手动配置 emulator