根據公司的要求,需要寫一個自定義圖檔編輯控件,可以放大縮小,删除,拖動等操作。
先寫一個自定義的控件StickerView代碼如下:
package com.ankoninc.imageview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.widget.ImageView;
import com.ankoninc.esdiagnose.R;
/**
* Created by lihu on 2017/4/18.
*/
public class StickerView extends ImageView {
private static final String Log_TAG = "DragImageView&&StickerView";
//删除圖示
private Bitmap deleteBitmap;
//放大縮小圖示
private Bitmap resizeBitmap;
private Bitmap mBitmap;
private Bitmap topBitmap;
private Bitmap flipBitmap;
private Rect dst_delete;
private Rect dst_resize;
private Rect dst_flipV;
private int deleteBitmapWidth;
private int deleteBitmapHeight;
private int resizeBitmapWidth;
private int resizeBitmapHeight;
//水準鏡像
private int flipVBitmapWidth;
private int flipVBitmapHeight;
//置頂
private int topBitmapWidth;
private int topBitmapHeight;
private Paint localPaint;
private int mScreenwidth;
private int mScrernHeight;
private PointF mid = new PointF();
private float lastRotateDegree;
private boolean isPointerDown = false;
//手指移動距離必須超過這個數值
private final float pointerLimitDis = 20f;
private final float pointerZoomCoeff = 0.09f;
/**
* 對角線的長度
*/
private float lastLength;
private boolean isInResize = false;
private Matrix matrix = new Matrix();
/**
* 是否在四條線的内部
*/
private boolean isInSide;
private float startX;
private float startY;
private float rightX;
private float rightY;
private float leftX;
private float leftY;
private float endX;
private float endY;
private float lastX, lastY;
/**
* 是否在編輯模式
*/
private boolean isInEdit = true;
private float MIN_SCALE = 0.5f;
private float MAX_SCALE = 1.2f;
private double halfDiagonalLength;
private float oringinWidth = 0;
//雙指縮放時的初始距離
private float oldDis;
private final long stickerId;
private DisplayMetrics dm;
private static final float BITMAP_SCALE = 0.7f;
private OperationListener operationListener;
public StickerView(Context context, MotionEvent event) {
super(context);
stickerId = 0;
mEvent = event;
init();
}
public StickerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
stickerId = 0;
init();
}
private void init() {
dst_delete = new Rect();
dst_resize = new Rect();
dst_flipV = new Rect();
localPaint = new Paint();
localPaint.setColor(getResources().getColor(R.color.transparent));
localPaint.setAntiAlias(true);
localPaint.setDither(true);
localPaint.setStyle(Paint.Style.STROKE);
localPaint.setStrokeWidth(2.0f);
dm = getResources().getDisplayMetrics();//擷取螢幕參數
mScreenwidth = dm.widthPixels;
mScreenwidth = dm.heightPixels;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mBitmap != null) {
float[] arrayOfFloat = new float[9];
matrix.getValues(arrayOfFloat);
float f1 = 0.0F * arrayOfFloat[0] + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f2 = 0.0F * arrayOfFloat[3] + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f3 = arrayOfFloat[0] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f4 = arrayOfFloat[3] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f5 = 0.0F * arrayOfFloat[0] + arrayOfFloat[1] * this.mBitmap.getHeight() + arrayOfFloat[2];
float f6 = 0.0F * arrayOfFloat[3] + arrayOfFloat[4] * this.mBitmap.getHeight() + arrayOfFloat[5];
float f7 = arrayOfFloat[0] * this.mBitmap.getWidth() + arrayOfFloat[1] * this.mBitmap.getHeight() + arrayOfFloat[2];
float f8 = arrayOfFloat[3] * this.mBitmap.getWidth() + arrayOfFloat[4] * this.mBitmap.getHeight() + arrayOfFloat[5];
canvas.save();
canvas.drawBitmap(mBitmap, matrix, null);
dst_delete.left = (int) (f1 - deleteBitmapWidth / 2);
dst_delete.right = (int) (f1 + deleteBitmapWidth / 2);
dst_delete.top = (int) (f2 - deleteBitmapHeight / 2);
dst_delete.bottom = (int) (f2 + deleteBitmapHeight / 2);
dst_resize.left = (int) (f7 - resizeBitmapWidth / 2);
dst_resize.right = (int) (f7 + resizeBitmapWidth / 2);
dst_resize.top = (int) (f8 - resizeBitmapHeight / 2);
dst_resize.bottom = (int) (f8 + resizeBitmapHeight / 2);
//确定儲存
dst_flipV.left = (int) (f3 - flipVBitmapWidth / 2);
dst_flipV.right = (int) (f3 + flipVBitmapWidth / 2);
dst_flipV.top = (int) (f4 - flipVBitmapHeight / 2);
dst_flipV.bottom = (int) (f4 + flipVBitmapHeight / 2);
if (isInEdit) {
RectF rectF = new RectF(f1, f2, f7, f8);
canvas.drawRect(rectF, localPaint);
canvas.drawBitmap(deleteBitmap, null, dst_delete, null);
canvas.drawBitmap(resizeBitmap, null, dst_resize, null);
canvas.drawBitmap(flipBitmap, null, dst_flipV, null);
startX = f1;
startY = f2;
rightX = f3;
rightY = f4;
leftX = f5;
leftY = f6;
endX = f7;
endY = f8;
}
canvas.restore();
}
}
public float getStartX() {
return startX;
}
public float getStartY() {
return startY;
}
public float getRightX() {
return rightX;
}
public float getRightY() {
return rightY;
}
public float getLeftX() {
return leftX;
}
public float getLeftY() {
return leftY;
}
public float getEndX() {
return endX;
}
public float getEndY() {
return endY;
}
@Override
public void setImageResource(int resId) {
setBitmap(BitmapFactory.decodeResource(getResources(), resId));
}
private MotionEvent mEvent;
public void setBitmap(Bitmap bitmap) {
matrix.reset();
mBitmap = getInitBitmap(bitmap);
setDiagonalLength();
initBitmaps();
int w = mBitmap.getWidth();
int h = mBitmap.getHeight();
oringinWidth = w;
float initScale = (MIN_SCALE + MAX_SCALE) / 16;
matrix.postScale(initScale, initScale, w / 2, h / 2);
//Y坐标為 (頂部操作欄+正方形圖)/2
matrix.postTranslate(mEvent.getX() - 3 * w / 4, mEvent.getY() - 3 * h / 4);
invalidate();
}
private void setDiagonalLength() {
halfDiagonalLength = Math.hypot(mBitmap.getWidth(), mBitmap.getHeight()) / 2;
}
/**
* 初始化 布局圖檔
* @param image
* @return
*/
private Bitmap getInitBitmap(Bitmap image) {
if (image == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = createDefaultPaint();
float[] arrayOfFloat = new float[9];
matrix.getValues(arrayOfFloat);
float f1 = 0.0F * arrayOfFloat[0] + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f2 = 0.0F * arrayOfFloat[3] + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f3 = arrayOfFloat[0] * bitmap.getWidth() + arrayOfFloat[1] * bitmap.getHeight() + arrayOfFloat[2];
float f4 = arrayOfFloat[3] * bitmap.getWidth() + arrayOfFloat[4] * bitmap.getHeight() + arrayOfFloat[5];
RectF rectF = new RectF(f1, f2, f3, f4);
canvas.drawRect(rectF, paint);
canvas.drawBitmap(image, matrix, paint);
return bitmap;
}
private Paint createDefaultPaint() {
Paint paint = new Paint();
paint.setColor(getResources().getColor(R.color.comTemplateButton0));
paint.setStrokeWidth(getResources().getDimension(R.dimen.stcker_width));
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
return paint;
}
private void initBitmaps() {
//當圖檔的寬比高大時 按照寬計算 縮放大小根據圖檔的大小而改變 最小為圖檔的1/8 最大為螢幕寬
if (mBitmap.getWidth() >= mBitmap.getHeight()) {
float minWidth = mScreenwidth / 24;
if (mBitmap.getWidth() < minWidth) {
MIN_SCALE = 1f;
} else {
MIN_SCALE = 1.0f * minWidth / mBitmap.getWidth();
}
if (mBitmap.getWidth() > mScreenwidth) {
MAX_SCALE = 1f;
} else {
MAX_SCALE = 1.0f * mScreenwidth / mBitmap.getWidth();
}
} else {
float minHeight = mScrernHeight / 24;
if (mBitmap.getHeight() < minHeight) {
MIN_SCALE = 1f;
} else {
MIN_SCALE = 1.0f * minHeight / mBitmap.getHeight();
}
if (mBitmap.getHeight() > mScreenwidth) {
MAX_SCALE = 1f;
} else {
MAX_SCALE = 1.0f * mScreenwidth / mBitmap.getHeight();
}
}
deleteBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_delete);
resizeBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_resize);
flipBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_flip);
deleteBitmapWidth = (int) (deleteBitmap.getWidth() * BITMAP_SCALE);
deleteBitmapHeight = (int) (deleteBitmap.getHeight() * BITMAP_SCALE);
resizeBitmapWidth = (int) (resizeBitmap.getWidth() * BITMAP_SCALE);
resizeBitmapHeight = (int) (resizeBitmap.getHeight() * BITMAP_SCALE);
flipVBitmapWidth = (int) (flipBitmap.getWidth() * BITMAP_SCALE);
flipVBitmapHeight = (int) (flipBitmap.getHeight() * BITMAP_SCALE);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
boolean handled = true;
switch (action) {
case MotionEvent.ACTION_DOWN:
if (isInButton(event, dst_delete)) {
if (operationListener != null) {
operationListener.onDeleteClick();
}
} else if (isInButton(event, dst_flipV)) {
if (operationListener != null) {
operationListener.drawRectLine();
}
} else if (isInResize(event)) {
isInResize = true;
lastRotateDegree = rotationToStartPoint(event);
midPointToStartPoint(event); // 設定mid點的值
lastLength = diagonalLength(event);// 觸摸點到矩形中點的距離
} else if (isInBitmap(event)) {
isInSide = true;
lastX = event.getX(0);
lastY = event.getY(0);
} else {
handled = false;
}
break;
case MotionEvent.ACTION_MOVE:
//雙指縮放
if (isPointerDown) {
float scale;
float disNew = spacing(event);
if (disNew == 0 || disNew < pointerLimitDis) {
scale = 1;
} else {
scale = disNew / oldDis;
//縮放緩慢
scale = (scale - 1) * pointerZoomCoeff + 1;
}
float scaleTemp = (scale * Math.abs(dst_delete.left - dst_resize.left)) / oringinWidth;
if ((scaleTemp <= MIN_SCALE) && scale < 1 || (scaleTemp >= MAX_SCALE) && scale > 1) {
scale = 1;
} else {
lastLength = diagonalLength(event);
}
matrix.postScale(scale, scale, mid.x, mid.y);
invalidate();
} else if (isInResize) {
matrix.postRotate((rotationToStartPoint(event) - lastRotateDegree) * 2, mid.x, mid.y);
lastRotateDegree = rotationToStartPoint(event);
float scale = diagonalLength(event) / lastLength;
if (((diagonalLength(event) / halfDiagonalLength <= MIN_SCALE)) && scale < 1 ||
(diagonalLength(event) / halfDiagonalLength >= MAX_SCALE) && scale > 1) {
scale = 1;
if (!isInResize(event)) {
isInResize = false;
}
} else {
lastLength = diagonalLength(event);
}
matrix.postScale(scale, scale, mid.x, mid.y);
invalidate();
} else if (isInSide) {
float x = event.getX(0);
float y = event.getY(0);
matrix.postTranslate(x - lastX, y - lastY);
lastX = x;
lastY = y;
invalidate();
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (spacing(event) > pointerLimitDis) {
oldDis = spacing(event);
isPointerDown = true;
midPointToStartPoint(event);
} else {
isPointerDown = false;
}
isInSide = false;
isInResize = false;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
isInResize = false;
isInSide = false;
isPointerDown = false;
break;
}
if (handled && operationListener != null) {
operationListener.onEdit(this);
}
return handled;
}
private MotionEvent firstEvent;
/**
* 直接控制上層控件的改變,事件穿透,不用點選兩次
*
* @param event
*/
public void inResize(MotionEvent event) {
isInResize = true;
if (firstEvent == null) {
firstEvent = event;
lastRotateDegree = rotationToStartPoint(firstEvent);
midPointToStartPoint(firstEvent); // 設定mid點的值
lastLength = diagonalLength(firstEvent);// 觸摸點到矩形中點的距離 todo 觸摸點 連續變化
}
matrix.postRotate((rotationToStartPoint(event) - lastRotateDegree) * 2, mid.x, mid.y);//旋轉
lastRotateDegree = rotationToStartPoint(event);
float scale = diagonalLength(event) / lastLength;
if (((diagonalLength(event) / halfDiagonalLength <= MIN_SCALE)) && scale < 1 ||
(diagonalLength(event) / halfDiagonalLength >= MAX_SCALE) && scale > 1) {
scale = 1;
if (!isInResize(event)) {
isInResize = false;
}
} else {
lastLength = diagonalLength(event);
}
matrix.postScale(scale, scale, mid.x, mid.y);//縮放
invalidate();
}
/**
* 計算圖檔的角度等屬性
*
* @param event
* @return
*/
private boolean isInBitmap(MotionEvent event) {
float[] arrayOfFloat1 = new float[9];
this.matrix.getValues(arrayOfFloat1);
//左上角
float f1 = 0.0F * arrayOfFloat1[0] + 0.0F * arrayOfFloat1[1] + arrayOfFloat1[2];
float f2 = 0.0F * arrayOfFloat1[3] + 0.0F * arrayOfFloat1[4] + arrayOfFloat1[5];
//右上角
float f3 = arrayOfFloat1[0] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat1[1] + arrayOfFloat1[2];
float f4 = arrayOfFloat1[3] * this.mBitmap.getWidth() + 0.0F * arrayOfFloat1[4] + arrayOfFloat1[5];
//左下角
float f5 = 0.0F * arrayOfFloat1[0] + arrayOfFloat1[1] * this.mBitmap.getHeight() + arrayOfFloat1[2];
float f6 = 0.0F * arrayOfFloat1[3] + arrayOfFloat1[4] * this.mBitmap.getHeight() + arrayOfFloat1[5];
//右下角
float f7 = arrayOfFloat1[0] * this.mBitmap.getWidth() + arrayOfFloat1[1] * this.mBitmap.getHeight() + arrayOfFloat1[2];
float f8 = arrayOfFloat1[3] * this.mBitmap.getWidth() + arrayOfFloat1[4] * this.mBitmap.getHeight() + arrayOfFloat1[5];
float[] arrayOfFloat2 = new float[4];
float[] arrayOfFloat3 = new float[4];
//确定X方向的範圍
arrayOfFloat2[0] = f1;//左上的x
arrayOfFloat2[1] = f3;//右上的x
arrayOfFloat2[2] = f7;//右下的x
arrayOfFloat2[3] = f5;//左下的x
//确定Y方向的範圍
arrayOfFloat3[0] = f2;//左上的y
arrayOfFloat3[1] = f4;//右上的y
arrayOfFloat3[2] = f8;//右下的y
arrayOfFloat3[3] = f6;//左下的y
return pointInRect(arrayOfFloat2, arrayOfFloat3, event.getX(0), event.getY(0));
}
/**
* 判斷點是否在一個矩形内部
*
* @param xRange
* @param yRange
* @param x
* @param y
* @return
*/
private boolean pointInRect(float[] xRange, float[] yRange, float x, float y) {
//四條邊的長度
double a1 = Math.hypot(xRange[0] - xRange[1], yRange[0] - yRange[1]);
double a2 = Math.hypot(xRange[1] - xRange[2], yRange[1] - yRange[2]);
double a3 = Math.hypot(xRange[3] - xRange[2], yRange[3] - yRange[2]);
double a4 = Math.hypot(xRange[0] - xRange[3], yRange[0] - yRange[3]);
//待檢測點到四個點的距離
double b1 = Math.hypot(x - xRange[0], y - yRange[0]);
double b2 = Math.hypot(x - xRange[1], y - yRange[1]);
double b3 = Math.hypot(x - xRange[2], y - yRange[2]);
double b4 = Math.hypot(x - xRange[3], y - yRange[3]);
double u1 = (a1 + b1 + b2) / 2;
double u2 = (a2 + b2 + b3) / 2;
double u3 = (a3 + b3 + b4) / 2;
double u4 = (a4 + b4 + b1) / 2;
//矩形的面積
double s = a1 * a2;
//海倫公式 計算4個三角形面積
double ss = Math.sqrt(u1 * (u1 - a1) * (u1 - b1) * (u1 - b2))
+ Math.sqrt(u2 * (u2 - a2) * (u2 - b2) * (u2 - b3))
+ Math.sqrt(u3 * (u3 - a3) * (u3 - b3) * (u3 - b4))
+ Math.sqrt(u4 * (u4 - a4) * (u4 - b4) * (u4 - b1));
return Math.abs(s - ss) < 0.5;
}
/**
* 觸摸是否在某個button範圍
*
* @param event
* @param rect
* @return
*/
private boolean isInButton(MotionEvent event, Rect rect) {
int left = rect.left;
int right = rect.right;
int top = rect.top;
int bottom = rect.bottom;
return event.getX(0) >= left && event.getX(0) <= right && event.getY(0) >= top && event.getY(0) <= bottom;
}
/**
* 觸摸是否在拉伸區域内
*
* @param event
* @return
*/
private boolean isInResize(MotionEvent event) {
int left = -20 + this.dst_resize.left;
int top = -20 + this.dst_resize.top;
int right = 20 + this.dst_resize.right;
int bottom = 20 + this.dst_resize.bottom;
return event.getX(0) >= left && event.getX(0) <= right && event.getY(0) >= top && event.getY(0) <= bottom;
}
/**
* 觸摸的位置和圖檔左上角位置的中點
*
* @param event
*/
private void midPointToStartPoint(MotionEvent event) {
float[] arrayOfFloat = new float[9];
matrix.getValues(arrayOfFloat);
float f1 = 0.0f * arrayOfFloat[0] + 0.0f * arrayOfFloat[1] + arrayOfFloat[2];
float f2 = 0.0f * arrayOfFloat[3] + 0.0f * arrayOfFloat[4] + arrayOfFloat[5];
float f3 = f1 + event.getX(0);
float f4 = f2 + event.getY(0);
mid.set(f3 / 2, f4 / 2);
}
/**
* 計算對角線交叉的位置
*
* @param paramPointF
*/
private void midDiagonalPoint(PointF paramPointF) {
float[] arrayOfFloat = new float[9];
this.matrix.getValues(arrayOfFloat);
float f1 = 0.0F * arrayOfFloat[0] + 0.0F * arrayOfFloat[1] + arrayOfFloat[2];
float f2 = 0.0F * arrayOfFloat[3] + 0.0F * arrayOfFloat[4] + arrayOfFloat[5];
float f3 = arrayOfFloat[0] * this.mBitmap.getWidth() + arrayOfFloat[1] * this.mBitmap.getHeight() + arrayOfFloat[2];
float f4 = arrayOfFloat[3] * this.mBitmap.getWidth() + arrayOfFloat[4] * this.mBitmap.getHeight() + arrayOfFloat[5];
float f5 = f1 + f3;
float f6 = f2 + f4;
paramPointF.set(f5 / 2.0F, f6 / 2.0F);
}
/**
* 在滑動旋轉過程中,總是以左上角原點作為絕對坐标計算偏轉角度
*
* @param event
* @return
*/
private float rotationToStartPoint(MotionEvent event) {
float[] arrayOfFloat = new float[9];
matrix.getValues(arrayOfFloat);
float x = 0.0f * arrayOfFloat[0] + 0.0f * arrayOfFloat[1] + arrayOfFloat[2];
float y = 0.0f * arrayOfFloat[3] + 0.0f * arrayOfFloat[4] + arrayOfFloat[5];
double arc = Math.atan2(event.getY(0) - y, event.getX(0) - x);
return (float) Math.toDegrees(arc);
}
/**
* 觸摸點到矩形中點的距離
*
* @param event
* @return
*/
private float diagonalLength(MotionEvent event) {
float diagonalLength = (float) Math.hypot(event.getX(0) - mid.x, event.getY(0) - mid.y);
return diagonalLength;
}
/**
* 計算雙指之間的距離
*/
private float spacing(MotionEvent event) {
if (event.getPointerCount() == 2) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
} else {
return 0;
}
}
public interface OperationListener {
void onDeleteClick();
void onEdit(StickerView stickerView);
void drawRectLine();
}
public void setOperationListener(OperationListener operationListener) {
this.operationListener = operationListener;
}
public void setInEdit(boolean isInEdit) {
this.isInEdit = isInEdit;
invalidate();
}
}
在我們的項目當中,需要映射到另一張圖檔上
package com.ankoninc.imageview;
/**
* Created by Nick.Zhang on 2015/3/11.
*/
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.ankoninc.data.PointInfo;
import com.ankoninc.esdiagnose.AppContext;
import com.ankoninc.esdiagnose.R;
import com.ankoninc.utils.DensityUtils;
import com.ankoninc.utils.Log;
import java.util.ArrayList;
import java.util.List;
public class DragImageView extends ImageView {
private static final String LOG_TAG = "DragImageView";
private static final int DEFAULT_IMAGE_SIZE = 480;
private static final int LINE_STROKE_WIDTH = DensityUtils.dp2px(AppContext.getInstance(), 2);
private static final int FONT_SIZE = DensityUtils.dp2px(AppContext.getInstance(), 10);
private static final int TEXT_COLOR = Color.BLUE;
private static final int LINE_COLOR = 0xffffd10c;
public Bitmap mSrcBitmap;
public Bitmap tmpBitmap;
public Bitmap mDrawBitmap;
public boolean mEdit = false;
public List<PointInfo> mPointList = new ArrayList<PointInfo>();
public MARK mark = MARK.NONE;// 預設模式
private Rect currentRect = new Rect();
private PointF drawStartPoint = new PointF();
private PointF drawCurrentPoint = new PointF();
private PointF startPoint0 = new PointF();
private PointF startPoint1 = new PointF();
private PointF currentPoint0 = new PointF();
private float startLen;
private float currentLen;
private int minImageSize = DEFAULT_IMAGE_SIZE;
private int mDragWidth = 0;
private int mDragHeight = 0;
private MODE mode = MODE.NONE;// 預設模式
private RelativeLayout mRelativeLayout;
//設定開關,隻允許畫一次矩形
boolean isDragRect;
//目前的正方形的控件
private StickerView mCurrentView;
public DragImageView(Context context) {
this(context, null);
}
public DragImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setMark(MARK type) {
Log.d(LOG_TAG, "setMark: %s", type);
mark = type;
}
private Context mContext;
public void setRelativeLayout(RelativeLayout relativeLayout, Context context) {
this.mRelativeLayout = relativeLayout;
this.mContext = context;
}
public void setBitmapSrc(Bitmap src, List<PointInfo> pointList) {
Log.d(LOG_TAG, "setBitmapSrc: %s, %s", src, pointList);
mPointList = pointList;
mDrawBitmap = drawMarkImage(src, mPointList);
mSrcBitmap = src;
tmpBitmap = mDrawBitmap;
this.setImageBitmap(mDrawBitmap);
}
public void setDragSize(int width, int height) {
Log.d(LOG_TAG, "setDragSize: %s, %s", width, height);
int tmp = Math.abs(width - height);
this.setFrame(tmp / 2, 0, width - tmp / 2, height);
this.layout(tmp / 2, 0, width - tmp / 2, height);
mDragWidth = width;
mDragHeight = height;
}
public void resetBitmap() {
Log.d(LOG_TAG, "resetBitmap");
mDrawBitmap = mSrcBitmap;
tmpBitmap = mDrawBitmap;
mPointList.clear();
this.setImageBitmap(mSrcBitmap);
mEdit = false;
}
/**
* 編輯模式中重置開關,重置最後一次操作
*/
public void cancelLastDraw() {
if (mPointList == null || mPointList.size() <= 1) {
resetBitmap();
return;
}
int last = mPointList.size() - 1;
mPointList.remove(last);
setBitmapSrc(mSrcBitmap, mPointList);
}
/**
* 設定顯示圖檔
*/
@Override
public void setImageBitmap(Bitmap bm) {
Log.d(LOG_TAG, "setImageBitmap: %s", bm);
if (mode == MODE.NONE) {
Log.d(LOG_TAG, "setImageBitmap only save bitmap without mark.");
mDrawBitmap = bm;
}
super.setImageBitmap(bm);
}
/**
* touch 事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
Log.d(LOG_TAG, "onTouchEvent");
Log.d(LOG_TAG, "rawX: %s, rawY: %s, X: %s, Y: %s",
event.getRawX(), event.getRawY(), event.getX(), event.getY());
/** 處理單點、多點觸摸 **/
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.d(LOG_TAG, "ACTION_DOWN");
onTouchDown(event);
break;
// 多點觸摸
case MotionEvent.ACTION_POINTER_DOWN:
Log.d(LOG_TAG, "ACTION_POINTER_DOWN");
onPointerDown(event);
break;
case MotionEvent.ACTION_MOVE:
Log.d(LOG_TAG, "ACTION_MOVE");
onTouchMove(event);
break;
case MotionEvent.ACTION_UP:
isDragRect = false;
Log.d(LOG_TAG, "ACTION_UP");
if (mark != MARK.NONE && mode == MODE.DRAG) {
Log.d(LOG_TAG, "Add a new tag info");
PointInfo info = new PointInfo();
if (mark != MARK.RECT) {
info.setType(mark);
// TODO: 2017/4/24 區分開是矩形還是其他的形狀
PointF startPoint = new PointF();
PointF endPoint = new PointF();
if (mark == MARK.ARROW || mark == MARK.MEASURE || mark == MARK.CIRCLE) {
startPoint.set((drawStartPoint.x * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth(), (drawStartPoint.y * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth());
endPoint.set((drawCurrentPoint.x * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth(), (drawCurrentPoint.y * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth());
info.setStartPoint(startPoint);
info.setEndPoint(endPoint);
}
mPointList.add(info);
}
}
mode = MODE.NONE;
this.setImageBitmap(tmpBitmap);
break;
// 多點松開
case MotionEvent.ACTION_POINTER_UP:
Log.d(LOG_TAG, "ACTION_POINTER_UP");
mode = MODE.NONE;
break;
}
return true;
}
/**
* 繪制圖檔, 加載時繪圖
*
* @param image
* @param pointList
* @return
*/
public static Bitmap drawMarkImage(Bitmap image, List<PointInfo> pointList) {
Log.d(LOG_TAG, "drawMarkImage: %s, %s", image, pointList);
if (image == null || pointList == null || pointList.isEmpty()) {
return image;
}
Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = createDefaultPaint(Math.min(image.getWidth(), image.getHeight()));
canvas.drawBitmap(image, 0, 0, paint);
for (PointInfo pointInfo : pointList) {
PointF startPoint = pointInfo.getStartPoint();
PointF endPoint = pointInfo.getEndPoint();
PointF start = new PointF();
PointF end = new PointF();
if (startPoint != null && endPoint != null) {
start.set(startPoint.x * image.getWidth() / DEFAULT_IMAGE_SIZE, startPoint.y * image.getHeight() / DEFAULT_IMAGE_SIZE);
end.set(endPoint.x * image.getWidth() / DEFAULT_IMAGE_SIZE, endPoint.y * image.getHeight() / DEFAULT_IMAGE_SIZE);
MARK type = pointInfo.getType();
switch (type) {
case ARROW:
// 設定畫箭頭的style為實心
paint.setStyle(Paint.Style.FILL_AND_STROKE);
requestDrawAL(start.x, start.y, end.x, end.y, canvas, paint);
break;
case MEASURE:
paint.setStyle(Paint.Style.FILL_AND_STROKE);
measureAndDraw(start.x, start.y, end.x, end.y, canvas, paint);
break;
case CIRCLE:
RectF oval = new RectF(start.x, start.y, end.x, end.y);
Log.d(LOG_TAG, "start.x: %s, start.y: %s, end.x: %s, end.y: %s", start.x, start.y, end.x, end.y);
paint.setStyle(Paint.Style.STROKE);
canvas.drawOval(oval, paint);
break;
case RECT:
PointF leftPoint = pointInfo.getLeftPoint();
PointF rightPoint = pointInfo.getRightPoint();
PointF left = new PointF();
PointF right = new PointF();
left.set(leftPoint.x * image.getWidth() / DEFAULT_IMAGE_SIZE, leftPoint.y * image.getHeight() / DEFAULT_IMAGE_SIZE);
right.set(rightPoint.x * image.getWidth() / DEFAULT_IMAGE_SIZE, rightPoint.y * image.getHeight() / DEFAULT_IMAGE_SIZE);
canvas.drawLine(start.x, start.y, right.x, right.y, paint);
canvas.drawLine(right.x, right.y, end.x, end.y, paint);
canvas.drawLine(left.x, left.y, end.x, end.y, paint);
canvas.drawLine(left.x, left.y, start.x, start.y, paint);
break;
default:
break;
}
}
}
return bitmap;
}
/**
* 按下 *
*/
void onTouchDown(MotionEvent event) {
Log.d(LOG_TAG, "onTouchDown");
mode = MODE.DRAG;
currentRect.set(this.getLeft(), this.getTop(), this.getRight(), this.getBottom());
startPoint0.set(event.getRawX(), event.getRawY());
drawStartPoint.set(event.getX(), event.getY());
if (mark == MARK.RECT) {
if (!isDragRect) {
isDragRect = true;
addRectView(event);
}
}
}
/**
* 兩個手指 隻能放大縮小 *
*/
void onPointerDown(MotionEvent event) {
Log.d(LOG_TAG, "onPointerDown PointerCount: %s", event.getPointerCount());
if (event.getPointerCount() == 2) {
mode = MODE.ZOOM;
startLen = getDistance(event);
startPoint1.set(event.getRawX(), event.getRawY());
}
}
private static void requestDrawAL(float sx, float sy, float ex, float ey, Canvas canvas, Paint paint) {
requestDrawAL(sx, sy, ex, ey, false, true, canvas, paint);
}
private static void requestDrawAL(float sx, float sy, float ex, float ey,
boolean drawStartArrow, boolean drawEndArrow, Canvas canvas, Paint paint) {
int imageSize = Math.min(canvas.getWidth(), canvas.getHeight());
double L = Math.max(LINE_STROKE_WIDTH * imageSize / DEFAULT_IMAGE_SIZE, 1); // 底邊的一半
double H = 2 * L + 1; // 箭頭高度
double awrad = Math.atan(L / H); // 箭頭角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭頭的長度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3, y_3, x_4, y_4;
Path triangle;
// 畫起點三角形
if (drawStartArrow) {
x_3 = sx + arrXY_1[0]; // (x3,y3)是第一端點
y_3 = sy + arrXY_1[1];
x_4 = sx + arrXY_2[0]; // (x4,y4)是第二端點
y_4 = sy + arrXY_2[1];
triangle = new Path();
triangle.setFillType(Path.FillType.EVEN_ODD);
triangle.moveTo(sx, sy);
triangle.lineTo(safeParseDouble(x_3), safeParseDouble(y_3));
triangle.lineTo(safeParseDouble(x_4), safeParseDouble(y_4));
triangle.close();
canvas.drawPath(triangle, paint);
}
// 畫線
canvas.drawLine(sx, sy, ex, ey, paint);
// 畫終點三角形
if (drawEndArrow) {
x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端點
y_3 = ey - arrXY_1[1];
x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端點
y_4 = ey - arrXY_2[1];
triangle = new Path();
triangle.setFillType(Path.FillType.EVEN_ODD);
triangle.moveTo(ex, ey);
triangle.lineTo(safeParseDouble(x_3), safeParseDouble(y_3));
triangle.lineTo(safeParseDouble(x_4), safeParseDouble(y_4));
triangle.close();
canvas.drawPath(triangle, paint);
}
}
private static void measureAndDraw(float sx, float sy, float ex, float ey, Canvas canvas, Paint paint) {
requestDrawAL(sx, sy, ex, ey, true, true, canvas, paint);
int x0 = safeParseDouble(sx * DEFAULT_IMAGE_SIZE / canvas.getWidth());
int y0 = safeParseDouble(sy * DEFAULT_IMAGE_SIZE / canvas.getHeight());
int x1 = safeParseDouble(ex * DEFAULT_IMAGE_SIZE / canvas.getWidth());
int y1 = safeParseDouble(ey * DEFAULT_IMAGE_SIZE / canvas.getHeight());
double distance = getAllDistance(x0, y0, x1, y1);
Log.d(LOG_TAG, "distance: %s", distance);
String text = String.format("%.1fmm", distance);
int imageSize = Math.min(canvas.getWidth(), canvas.getHeight());
Paint textPaint = createTextPaint(imageSize);
float width = textPaint.measureText(text);
float pathWidth = Math.abs(ex - sx);
float textSx, textSy, textEx, textEy;
if (sx < ex) {
textSx = sx;
textSy = sy;
textEx = ex;
textEy = ey;
} else {
textSx = ex;
textSy = ey;
textEx = sx;
textEy = sy;
}
if (width > pathWidth) {
float step = (width - pathWidth) / 2 + 1;
if (Math.abs(ex - sx) < 1) {
textSy = Math.min(textSy, textEy) - step;
textEy = Math.max(textSy, textEy) + step;
} else if (Math.abs(ey - sy) < 1) {
textSx = textSx - step;
textEx = textEx + step;
} else {
float stepY = step * Math.abs(ey - sy) / Math.abs(ex - sx);
textSx = textSx - step;
textSy = textSy - (textSy < textEy ? 1 : -1) * stepY;
textEx = textEx + step;
textEy = textEy + (textEy > textSy ? 1 : -1) * stepY;
}
}
Log.d(LOG_TAG, "Raw(%s, %s), (%s, %s), Text(%s, %s), (%s, %s)", sx, sy, ex, ey, textSx, textSy, textEx, textEy);
Path path = new Path();
path.moveTo(textSx, textSy);
path.lineTo(textEx, textEy);
canvas.drawTextOnPath(text, path, 0, 0, textPaint);
}
private static double getAllDistance(int x0, int y0, int x1, int y1) {
double distance0 = 0.0000f;
double distance1 = 0.0000f;
Point c = new Point();
int tmpAx, tmpAy, tmpBx, tmpBy;
int center = DEFAULT_IMAGE_SIZE / 2;
tmpAx = Math.abs(x0 - center);
tmpAy = Math.abs(y1 - center);
tmpBx = Math.abs(x1 - center);
tmpBy = Math.abs(y0 - center);
if ((tmpAx * tmpAx + tmpAy * tmpAy) >= (tmpBx * tmpBx + tmpBy * tmpBy)) {
c.set(x1, y0);
} else {
c.set(x0, y1);
}
if (x0 == x1) {
for (int i = Math.min(y0, y1); i <= Math.max(y0, y1); i++) {
distance1 += getPixelDistance(x0, i);
}
} else if (y0 == y1) {
for (int i = Math.min(x0, x1); i <= Math.max(x0, x1); i++) {
distance0 += getPixelDistance(i, y0);
}
} else {
if (c.x == x0) {
for (int i = Math.min(x0, x1); i <= Math.max(x0, x1); i++) {
distance0 += getPixelDistance(i, c.y);
}
for (int i = Math.min(c.y, y0); i <= Math.max(c.y, y0); i++) {
distance1 += getPixelDistance(x0, i);
}
} else if (c.x == x1) {
for (int i = Math.min(x0, x1); i <= Math.max(x0, x1); i++) {
distance0 += getPixelDistance(i, c.y);
}
for (int i = Math.min(c.y, y1); i <= Math.max(c.y, y1); i++) {
distance1 += getPixelDistance(x0, i);
}
}
}
return Math.sqrt(distance0 * distance0 + distance1 * distance1);
}
private static double getPixelDistance(int x0, int y0) {
int tmpX, tmpY;
double a = 0.0241f;
double t1 = 0.000026695f;
double t2 = 0.0353f;
double m, distance;
tmpX = Math.abs(240 - x0);
tmpY = Math.abs(240 - y0);
m = Math.sqrt(tmpX * tmpX + tmpY * tmpY);
distance = a + t1 * Math.exp(t2 * m);
if (distance > 0.08) {
distance = 0.08;
}
return distance;
}
private static int safeParseDouble(double value) {
Double result = value;
return result.intValue();
}
private static double[] rotateVec(float px, float py, double ang, boolean isChLen, double newLen) {
double mathstr[] = new double[2];
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
private static Paint createDefaultPaint(int imageSize) {
Paint paint = new Paint();
paint.setColor(LINE_COLOR);
int lineWidth = LINE_STROKE_WIDTH * imageSize / DEFAULT_IMAGE_SIZE;
paint.setStrokeWidth(Math.max(lineWidth, 1));
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
return paint;
}
private static Paint createTextPaint(int imageSize) {
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(TEXT_COLOR);
int fontSize = FONT_SIZE * imageSize / DEFAULT_IMAGE_SIZE;
paint.setTextSize(Math.max(fontSize, 10));
paint.setTextAlign(Paint.Align.CENTER);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
return paint;
}
/**
* 移動的處理 *
*/
void onTouchMove(MotionEvent event) {
Log.d(LOG_TAG, "onTouchMove begin");
if (mode == MODE.DRAG) {
Log.d(LOG_TAG, "onTouchMove in MODE.DRAG");
currentPoint0.set(event.getRawX(), event.getRawY());
drawCurrentPoint.set(event.getX(), event.getY());
int x = (int) (currentPoint0.x - startPoint0.x);
int y = (int) (currentPoint0.y - startPoint0.y);
Log.d(LOG_TAG, "distance x: %s, y: %s", x, y);
if (mark == MARK.NONE) {
if (mCurrentView != null) {
mCurrentView.setInEdit(false);
}
Log.d(LOG_TAG, "onTouchMove with MARK.NONE");
int left = currentRect.left + x;
int top = currentRect.top + y;
int right = currentRect.right + x;
int bottom = currentRect.bottom + y;
Log.d(LOG_TAG, "before left: %s, top: %s, right: %s, bottom: %s",
left, top, right, bottom);
if (left < -this.getWidth() / 2) {
left = -this.getWidth() / 2;
right = this.getWidth() / 2;
} else if (right > mDragWidth + this.getWidth() / 2) {
left = mDragWidth - this.getWidth() / 2;
right = mDragWidth + this.getWidth() / 2;
}
if (top < -this.getHeight() / 2) {
top = -this.getHeight() / 2;
bottom = this.getHeight() / 2;
} else if (bottom > mDragHeight + this.getWidth() / 2) {
top = mDragHeight - this.getHeight() / 2;
bottom = mDragHeight + this.getHeight() / 2;
}
Log.d(LOG_TAG, "after left: %s, top: %s, right: %s, bottom: %s",
left, top, right, bottom);
this.layout(left, top, right, bottom);
} else if ((x * x + y * y) > 100 && (mark == MARK.ARROW || mark == MARK.MEASURE || mark == MARK.CIRCLE)) {
Bitmap dest = Bitmap.createBitmap(mDrawBitmap.getWidth(), mDrawBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(dest);
Paint paint = createDefaultPaint(Math.max(mDrawBitmap.getWidth(), mDrawBitmap.getHeight()));
canvas.drawBitmap(mDrawBitmap, 0, 0, paint);
if (mCurrentView != null) {
mCurrentView.setInEdit(false);
}
float sx = drawStartPoint.x * mSrcBitmap.getWidth() / this.getWidth();
float sy = drawStartPoint.y * mSrcBitmap.getHeight() / this.getHeight();
float ex = drawCurrentPoint.x * mSrcBitmap.getWidth() / this.getWidth();
float ey = drawCurrentPoint.y * mSrcBitmap.getHeight() / this.getHeight();
if (mark == MARK.CIRCLE) {
Log.d(LOG_TAG, "onTouchMove with MARK.CIRCLE and moved a distance");
RectF oval = new RectF(sx, sy, ex, ey);
canvas.drawOval(oval, paint);
} else {
Log.d(LOG_TAG, "onTouchMove with MARK.ARROW and moved a distance");
// 設定畫箭頭的paint為實心
paint.setStyle(Paint.Style.FILL_AND_STROKE);
if (mark == MARK.MEASURE) {
measureAndDraw(sx, sy, ex, ey, canvas, paint);
} else {
requestDrawAL(sx, sy, ex, ey, canvas, paint);
}
}
this.setImageBitmap(dest);
tmpBitmap = dest;
mEdit = true;
} else if (mark == MARK.RECT) {
// TODO: 2017/4/20 拖動 頂層控件
mCurrentView.inResize(event);
}
} else if (mode == MODE.ZOOM) {
Log.d(LOG_TAG, "onTouchMove in MODE.ZOOM");
currentLen = getDistance(event);
float scale = currentLen - startLen;
int size = (int) scale;
if ((currentRect.right - currentRect.left + 2 * size) > minImageSize) {
this.setFrame(currentRect.left - size, currentRect.top - size, currentRect.right + size, currentRect.bottom + size);
}
}
Log.d(LOG_TAG, "onTouchMove finish");
}
public void closeRect() {
if (mCurrentView != null) {
mRelativeLayout.removeView(mCurrentView);
}
}
/**
* 添加 矩形
*/
private void addRectView(MotionEvent event) {
final StickerView stickerView = new StickerView(mContext, event);
stickerView.setImageResource(R.drawable.draw_rect);
stickerView.setOperationListener(new StickerView.OperationListener() {
@Override
public void onDeleteClick() {
mRelativeLayout.removeView(stickerView);
}
@Override
public void onEdit(StickerView stickerView) {
mCurrentView.setInEdit(false);
mCurrentView = stickerView;// 這裡是新舊交換
mCurrentView.setInEdit(true);
}
@Override
public void drawRectLine() {
drawRect();
mRelativeLayout.removeView(stickerView);
}
});
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
mRelativeLayout.addView(stickerView, lp);
setCurrentEdit(stickerView);
}
/**
* 當點選确定時畫矩形,添加新的矩形時畫上一個矩形
*/
private void drawRect() {
Bitmap dest = Bitmap.createBitmap(mDrawBitmap.getWidth(), mDrawBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(dest);
Paint paint = createDefaultPaint(Math.max(mDrawBitmap.getWidth(), mDrawBitmap.getHeight()));
canvas.drawBitmap(mDrawBitmap, 0, 0, paint);
PointInfo info = new PointInfo();
info.setType(mark);
// 計算4個頂點的位置
float startx = (mCurrentView.getStartX() * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float starty = (mCurrentView.getStartY() * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float rightx = (mCurrentView.getRightX() * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float righty = (mCurrentView.getRightY() * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float leftx = (mCurrentView.getLeftX() * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float lefty = (mCurrentView.getLeftY() * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float endx = (mCurrentView.getEndX() * mSrcBitmap.getWidth() / this.getWidth()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
float endy = (mCurrentView.getEndY() * mSrcBitmap.getHeight() / this.getHeight()) * DEFAULT_IMAGE_SIZE / mSrcBitmap.getWidth();
PointF startPoint = new PointF();
PointF endPoint = new PointF();
PointF rightPoint = new PointF();
PointF leftPoint = new PointF();
if (mark == MARK.RECT) {
startPoint.set(startx, starty);
rightPoint.set(rightx, righty);
leftPoint.set(leftx, lefty);
endPoint.set(endx, endy);
info.setStartPoint(startPoint);
info.setEndPoint(endPoint);
info.setRightPoint(rightPoint);
info.setLeftPoint(leftPoint);
}
mPointList.add(info);
mode = MODE.NONE;
// 畫正方形,因為控件是一個正方形,是以隻能畫四條邊
canvas.drawLine(startx, starty, rightx, righty, paint);
canvas.drawLine(rightx, righty, endx, endy, paint);
canvas.drawLine(leftx, lefty, endx, endy, paint);
canvas.drawLine(leftx, lefty, startx, starty, paint);
this.setImageBitmap(dest);
tmpBitmap = dest;
mEdit = true;
}
/**
* 設定目前處于編輯模式的貼紙
*/
private void setCurrentEdit(StickerView stickerView) {
if (mCurrentView != null) {
mCurrentView.setInEdit(false);
}
mCurrentView = stickerView;
stickerView.setInEdit(true);
}
/**
* 擷取兩點的距離 *
*/
float getDistance(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private enum MODE {
NONE, DRAG, ZOOM
}
public enum MARK {
// 不要修改名稱,因為acil裡面存的就是string型的名稱,而不是id,改名稱之後容易比對不到類型
NONE, ARROW, CIRCLE, MEASURE, RECT;
public static MARK get(int ordinal) {
for (MARK mark : MARK.values()) {
if (mark.ordinal() == ordinal) {
return mark;
}
}
return NONE;
}
}
}