1. 程式人生 > >自定義控制元件:手勢縮放移動,遮罩

自定義控制元件:手勢縮放移動,遮罩


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import
android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import com.lhcm.print.imageprinter.R; /** * Created by chenweiqi on 2017/1/12. */
public class TouchView extends View { float x_down = 0; float y_down = 0; PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; float oldRotation = 0; Matrix matrix = new Matrix(); Matrix matrix1 = new Matrix(); Matrix savedMatrix = new Matrix(); Matrix desMatrix ; private
static final int NONE = 0; private static final int DRAG = 1; private static final int ZOOM = 2; int mode = NONE; boolean matrixCheck = false; int widthScreen; int heightScreen; Bitmap source; Bitmap des; Rect borderRect; boolean isNeedPaintBorder = false; boolean isNeedPaintText = false; Paint borderPaint; String paintText = "相片超出邊界"; int viewHeight; int viewWidth; Paint paint; boolean doOnDraw = false; boolean touchAble = true; public TouchView(Context context) { this(context,null); } public TouchView(Context context, AttributeSet attrs) { super(context, attrs); source = BitmapFactory.decodeResource(getResources(), R.mipmap.test2); DisplayMetrics dm = new DisplayMetrics(); ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm); widthScreen = dm.widthPixels; heightScreen = dm.heightPixels; matrix = new Matrix(); des = BitmapFactory.decodeResource(getResources(), R.mipmap.star); borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); borderPaint.setColor(Color.RED); borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setStrokeWidth(3); borderRect = new Rect(); paint = new Paint(); paint.setAntiAlias(true); } protected void onDraw(Canvas canvas) { viewHeight = getHeight(); viewWidth = getWidth(); paint.setAntiAlias(true); canvas.save(); int saveLayerCount = canvas.saveLayer(0, 0, viewWidth, viewHeight, paint, Canvas.ALL_SAVE_FLAG); if(source!=null) { canvas.drawBitmap(source, matrix, null); } if (des!=null) { if (desMatrix == null) { desMatrix = new Matrix(); desMatrix.setScale(viewWidth * 1f / des.getWidth(), viewHeight * 1f / des.getHeight()); } paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); canvas.drawBitmap(des, desMatrix, paint); paint.setXfermode(null); } if (isNeedPaintBorder){ paintViewBorder(canvas); } if (isNeedPaintText) { paintText(canvas); } canvas.restoreToCount(saveLayerCount); canvas.restore(); doOnDraw = true; System.gc(); } public boolean onTouchEvent(MotionEvent event) { doOnDraw = false; switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: isNeedPaintBorder = true; mode = DRAG; x_down = event.getX(); y_down = event.getY(); savedMatrix.set(matrix); invalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: mode = ZOOM; oldDist = spacing(event); oldRotation = rotation(event); savedMatrix.set(matrix); midPoint(mid, event); break; case MotionEvent.ACTION_MOVE: if (mode == ZOOM) { matrix1.set(savedMatrix); float rotation = rotation(event) - oldRotation; float newDist = spacing(event); float scale = newDist / oldDist; matrix1.postScale(scale, scale, mid.x, mid.y);// 縮放 matrix1.postRotate(rotation, mid.x, mid.y);// 旋轉 matrixCheck = matrixCheck(); if (matrixCheck == false) { matrix.set(matrix1); invalidate(); } } else if (mode == DRAG) { matrix1.set(savedMatrix); matrix1.postTranslate(event.getX() - x_down, event.getY()- y_down);// 平移 if (!matrixCheck()) { matrix.set(matrix1); invalidate(); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; isNeedPaintBorder = false; invalidate(); break; } return touchAble; } private boolean matrixCheck() { float[] f = new float[9]; matrix1.getValues(f); // 圖片4個頂點的座標 float x1 = f[0] * 0 + f[1] * 0 + f[2]; float y1 = f[3] * 0 + f[4] * 0 + f[5]; float x2 = f[0] * source.getWidth() + f[1] * 0 + f[2]; float y2 = f[3] * source.getWidth() + f[4] * 0 + f[5]; float x3 = f[0] * 0 + f[1] * source.getHeight() + f[2]; float y3 = f[3] * 0 + f[4] * source.getHeight() + f[5]; float x4 = f[0] * source.getWidth() + f[1] * source.getHeight() + f[2]; float y4 = f[3] * source.getWidth() + f[4] * source.getHeight() + f[5]; // 圖片現寬度 double width = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); // 縮放比率判斷 if (width < viewWidth / 3 || width > viewHeight * 3) { return true; } // 出界判斷 int ds= 3; if ((y1>viewHeight+ds&&y2>viewHeight+ds&&y3>viewHeight+ds&&y4>viewHeight+ds) ||(y1<-ds&&y2<-ds&&y3<-ds&&y4<-ds) ||(x1>viewWidth+ds&&x2>viewWidth+ds&&x3>viewWidth+ds&&x4>viewWidth+ds) ||(x1<-ds&&x2<-ds&&x3<-ds&&x4<-ds)){ isNeedPaintText = true; return true; }else { isNeedPaintText = false; } return false; } // 觸碰兩點間距離 private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y); } // 取手勢中心點 private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } // 取旋轉角度 private float rotation(MotionEvent event) { double delta_x = (event.getX(0) - event.getX(1)); double delta_y = (event.getY(0) - event.getY(1)); double radians = Math.atan2(delta_y, delta_x); return (float) Math.toDegrees(radians); } // 將移動,縮放以及旋轉後的圖層儲存為新圖片 public Bitmap creatNewPhoto() { Bitmap bitmap = Bitmap.createBitmap(widthScreen, heightScreen, Bitmap.Config.ARGB_8888); // 背景圖片 Canvas canvas = new Canvas(bitmap); // 新建畫布 canvas.drawBitmap(source, matrix, null); // 畫圖片 canvas.save(Canvas.ALL_SAVE_FLAG); // 儲存畫布 canvas.restore(); return bitmap; } //畫邊界 private void paintViewBorder(Canvas canvas){ getLocalVisibleRect(borderRect); borderRect.top+=3; borderRect.bottom-=3; borderRect.left+=3; borderRect.right-=3; canvas.drawRect(borderRect,borderPaint); } private void paintText(Canvas canvas){ Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); textPaint.setTextSize(35); textPaint.setColor(Color.RED); Paint.FontMetrics fontMetrics = textPaint.getFontMetrics(); Rect textRect = new Rect(); textPaint.getTextBounds(paintText,0,paintText.length(),textRect); int x = (viewWidth-textRect.right+textRect.left)/2; int y = (int) ((viewHeight*1f-textRect.bottom+textRect.top)/2+(fontMetrics.bottom-fontMetrics.top)/2); canvas.drawText(paintText, x, y, textPaint); } @Override public Matrix getMatrix() { return matrix; } public void setMatrix(Matrix matrix) { this.matrix = matrix; invalidate(); } @Override public void invalidate() { super.invalidate(); if (!doOnDraw) { ((View) getParent()).invalidate(); } } public void setSourceBitmap(Bitmap source){ this.source = source; } public void setDesBitmap(Bitmap des){ this.des = des; } public void setTouchAble(boolean touchAble){ this.touchAble = touchAble; } }

這裡寫圖片描述