Android(安卓)matrix 控制图片的旋转、缩放、移动
16lz
2022-06-03
本文主要讲解利用android中Matrix控制图形的旋转缩放移动,具体参见一下代码:
view plainprint?- /**
- *使用矩阵控制图片移动、缩放、旋转
- *@author张进
- */
- publicclassCommonImgEffectViewextendsView{
- privateContextcontext;
- privateBitmapmainBmp,controlBmp;
- privateintmainBmpWidth,mainBmpHeight,controlBmpWidth,controlBmpHeight;
- privateMatrixmatrix;
- privatefloat[]srcPs,dstPs;
- privateRectFsrcRect,dstRect;
- privatePaintpaint,paintRect,paintFrame;
- privatefloatdeltaX=0,deltaY=0;//位移值
- privatefloatscaleValue=1;//缩放值
- privatePointlastPoint;
- privatePointprePivot,lastPivot;
- privatefloatpreDegree,lastDegree;
- privateshortcurrentSelectedPointindex;//当前操作点击点
- privatePointsymmetricPoint=newPoint();//当前操作点对称点
- /**
- *图片操作类型
- */
- publicstaticfinalintOPER_DEFAULT=-1;//默认
- publicstaticfinalintOPER_TRANSLATE=0;//移动
- publicstaticfinalintOPER_SCALE=1;//缩放
- publicstaticfinalintOPER_ROTATE=2;//旋转
- publicstaticfinalintOPER_SELECTED=3;//选择
- publicintlastOper=OPER_DEFAULT;
- /*图片控制点
- *0---1---2
- *||
- *783
- *||
- *6---5---4
- */
- publicstaticfinalintCTR_NONE=-1;
- publicstaticfinalintCTR_LEFT_TOP=0;
- publicstaticfinalintCTR_MID_TOP=1;
- publicstaticfinalintCTR_RIGHT_TOP=2;
- publicstaticfinalintCTR_RIGHT_MID=3;
- publicstaticfinalintCTR_RIGHT_BOTTOM=4;
- publicstaticfinalintCTR_MID_BOTTOM=5;
- publicstaticfinalintCTR_LEFT_BOTTOM=6;
- publicstaticfinalintCTR_LEFT_MID=7;
- publicstaticfinalintCTR_MID_MID=8;
- publicintcurrent_ctr=CTR_NONE;
- publicCommonImgEffectView(Contextcontext){
- super(context);
- this.context=context;
- }
- publicCommonImgEffectView(Contextcontext,AttributeSetattrs){
- super(context,attrs);
- this.context=context;
- initData();
- }
- /**
- *初始化数据
- *@author张进
- */
- privatevoidinitData(){
- 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=newfloat[]{
- 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=newRectF(0,0,mainBmpWidth,mainBmpHeight);
- dstRect=newRectF();
- matrix=newMatrix();
- prePivot=newPoint(mainBmpWidth/2,mainBmpHeight/2);
- lastPivot=newPoint(mainBmpWidth/2,mainBmpHeight/2);
- lastPoint=newPoint(0,0);
- paint=newPaint();
- paintRect=newPaint();
- paintRect.setColor(Color.RED);
- paintRect.setAlpha(100);
- paintRect.setAntiAlias(true);
- paintFrame=newPaint();
- paintFrame.setColor(Color.GREEN);
- paintFrame.setAntiAlias(true);
- setMatrix(OPER_DEFAULT);
- }
- /**
- *矩阵变换,达到图形平移的目的
- *@author张进
- */
- privatevoidsetMatrix(intoperationType){
- switch(operationType){
- caseOPER_TRANSLATE:
- matrix.postTranslate(deltaX,deltaY);
- break;
- caseOPER_SCALE:
- matrix.postScale(scaleValue,scaleValue,symmetricPoint.x,symmetricPoint.y);
- break;
- caseOPER_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);
- }
- privatebooleanisOnPic(intx,inty){
- if(dstRect.contains(x,y)){
- returntrue;
- }else
- returnfalse;
- }
- privateintgetOperationType(MotionEventevent){
- intevX=(int)event.getX();
- intevY=(int)event.getY();
- intcurOper=lastOper;
- switch(event.getAction()){
- caseMotionEvent.ACTION_DOWN:
- current_ctr=isOnCP(evX,evY);
- Log.i("img","current_ctris"+current_ctr);
- if(current_ctr!=CTR_NONE||isOnPic(evX,evY)){
- curOper=OPER_SELECTED;
- }
- break;
- caseMotionEvent.ACTION_MOVE:
- if(current_ctr>CTR_NONE&¤t_ctr<CTR_MID_MID){
- curOper=OPER_SCALE;
- }elseif(current_ctr==CTR_MID_MID){
- curOper=OPER_ROTATE;
- }elseif(lastOper==OPER_SELECTED){
- curOper=OPER_TRANSLATE;
- }
- break;
- caseMotionEvent.ACTION_UP:
- curOper=OPER_SELECTED;
- break;
- default:
- break;
- }
- Log.d("img","curOperis"+curOper);
- returncurOper;
- }
- /**
- *判断点所在的控制点
- *@paramevX
- *@paramevY
- *@return
- */
- privateintisOnCP(intevx,intevy){
- Rectrect=newRect(evx-controlBmpWidth/2,evy-controlBmpHeight/2,evx+controlBmpWidth/2,evy+controlBmpHeight/2);
- intres=0;
- for(inti=0;i<dstPs.length;i+=2){
- if(rect.contains((int)dstPs[i],(int)dstPs[i+1])){
- returnres;
- }
- ++res;
- }
- returnCTR_NONE;
- }
- @Override
- publicbooleandispatchTouchEvent(MotionEventevent){
- intevX=(int)event.getX();
- intevY=(int)event.getY();
- intoperType=OPER_DEFAULT;
- operType=getOperationType(event);
- switch(operType){
- caseOPER_TRANSLATE:
- translate(evX,evY);
- break;
- caseOPER_SCALE:
- scale(event);
- break;
- caseOPER_ROTATE:
- rotate(event);
- break;
- }
- lastPoint.x=evX;
- lastPoint.y=evY;
- lastOper=operType;
- invalidate();//重绘
- returntrue;
- }
- /**
- *移动
- *@paramevx
- *@paramevy
- *@authorzhang_jin1
- */
- privatevoidtranslate(intevx,intevy){
- 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
- *||
- *783
- *||
- *6---5---4
- *@paramevX
- *@paramevY
- */
- privatevoidscale(MotionEventevent){
- intpointIndex=current_ctr*2;
- floatpx=dstPs[pointIndex];
- floatpy=dstPs[pointIndex+1];
- floatevx=event.getX();
- floatevy=event.getY();
- floatoppositeX=0;
- floatoppositeY=0;
- if(current_ctr<4&¤t_ctr>=0){
- oppositeX=dstPs[pointIndex+8];
- oppositeY=dstPs[pointIndex+9];
- }elseif(current_ctr>=4){
- oppositeX=dstPs[pointIndex-8];
- oppositeY=dstPs[pointIndex-7];
- }
- floattemp1=getDistanceOfTwoPoints(px,py,oppositeX,oppositeY);
- floattemp2=getDistanceOfTwoPoints(evx,evy,oppositeX,oppositeY);
- this.scaleValue=temp2/temp1;
- symmetricPoint.x=(int)oppositeX;
- symmetricPoint.y=(int)oppositeY;
- Log.i("img","scaleValueis"+scaleValue);
- setMatrix(OPER_SCALE);
- }
- /**
- *旋转图片
- *0---1---2
- *||
- *783
- *||
- *6---5---4
- *@paramevX
- *@paramevY
- */
- privatevoidrotate(MotionEventevent){
- if(event.getPointerCount()==2){
- preDegree=computeDegree(newPoint((int)event.getX(0),(int)event.getY(0)),newPoint((int)event.getX(1),(int)event.getY(1)));
- }else{
- preDegree=computeDegree(newPoint((int)event.getX(),(int)event.getY()),newPoint((int)dstPs[16],(int)dstPs[17]));
- }
- setMatrix(OPER_ROTATE);
- lastDegree=preDegree;
- }
- /**
- *计算两点与垂直方向夹角
- *@paramp1
- *@paramp2
- *@return
- */
- publicfloatcomputeDegree(Pointp1,Pointp2){
- floattran_x=p1.x-p2.x;
- floattran_y=p1.y-p2.y;
- floatdegree=0.0f;
- floatangle=(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;
- }elseif(tran_x<=0&&tran_y<=0){//第二象限
- degree=angle;
- }elseif(tran_x<=0&&tran_y>=0){//第三象限
- degree=-180-angle;
- }elseif(tran_x>=0&&tran_y>=0){//第四象限
- degree=180-angle;
- }
- }
- returndegree;
- }
- /**
- *计算两个点之间的距离
- *@paramp1
- *@paramp2
- *@return
- */
- privatefloatgetDistanceOfTwoPoints(Pointp1,Pointp2){
- return(float)(Math.sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
- }
- privatefloatgetDistanceOfTwoPoints(floatx1,floaty1,floatx2,floaty2){
- return(float)(Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
- }
- @Override
- publicvoidonDraw(Canvascanvas){
- drawBackground(canvas);//绘制背景,以便测试矩形的映射
- canvas.drawBitmap(mainBmp,matrix,paint);//绘制主图片
- drawFrame(canvas);//绘制边框,以便测试点的映射
- drawControlPoints(canvas);//绘制控制点图片
- }
- privatevoiddrawBackground(Canvascanvas){
- canvas.drawRect(dstRect,paintRect);
- }
- privatevoiddrawFrame(Canvascanvas){
- 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);
- }
- privatevoiddrawControlPoints(Canvascanvas){
- for(inti=0;i<dstPs.length;i+=2){
- canvas.drawBitmap(controlBmp,dstPs[i]-controlBmpWidth/2,dstPs[i+1]-controlBmpHeight/2,paint);
- }
- }
- }
Demo效果:
更多相关文章
- Android(安卓)使用Vitamio实现播放视频(一)
- Android(安卓)图形学原理之OpenGL ES
- android图片缩放(指定大小)
- 优化布局在Android–减少过度渲染
- android图片缩放(指定大小)
- android 生成圆角和带倒影图片
- android 按钮的点击缩放
- Android(安卓)图片缩放实例详解
- android获取图库图片并返回