我已经创建了自己的ImageView 在两点之间进行叠加,缩放,平移和测量。
到目前为止,除了测量工作之外,canvas.drawline什么都没有显示?
这可能很脏,很可能会被清理干净。 任何人都知道为什么canvas.drawline不起作用?
先谢谢
public class myImage extends ImageView implements OnTouchListener {
private static final short UNKNOWN = 0;
private static final short IMG_INIT = 1;
private static final short SET_IMAGE = 2;
private static final short DRAGGING = 3;
private static final short MARKING = 4;
private static final short STARTING = 5;
private static final short ZOOM_PAN = 6;
private static final short OVERLAY = 7;
private static short STATE = UNKNOWN;
private static PointF pointA = null;
private static PointF pointB = null;
private static PointF pointC = null;
private PointF busy = new PointF();
private Bitmap tracking = BitmapFactory.decodeResource(getResources(), R.drawable.target);
private Drawable[] layers = new Drawable[2];
private Paint mPaint;
private Bitmap mBitmap;
private Canvas busyCanvas;
private int touch_counter = 0;
@Override
protected void onDraw(Canvas canvas) {
switch (STATE) {
/* 0 */ case UNKNOWN: super.onDraw(canvas); break;
/* 1 */ case IMG_INIT: break;
/* 2 */ case SET_IMAGE: super.onDraw(canvas); break;
/* 3 */ case DRAGGING: break;
/* 4 */ case MARKING:
canvas.drawBitmap(mBitmap, matrix, mPaint);
if (touch_counter == 0 && pointB != null && CURRENT_STATUS == "DRAW_LINE" ) {
mPaint.setColor(Color.BLUE);
canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, mPaint);
This is What does Not Show up OR work
}
break;
/* 5 */ case STARTING: break;
/* 6 */ case ZOOM_PAN: super.onDraw(canvas); break;
/* 7 */ case OVERLAY: super.onDraw(canvas); break;
}
STATE = UNKNOWN;
}
public void InitOverlay(String fName) {
fName = "/sdcard/DCIM/"+fName;
if ( (fName.endsWith(".jpg") || fName.endsWith(".png")) ) {
Matrix matrix = new Matrix();
matrix.postScale(0.35f, 0.35f);
Bitmap bitm2 = BitmapFactory.decodeFile( fName );
layers[0] = new BitmapDrawable( mBitmap ); layers[0].setAlpha(255);
layers[1] = new BitmapDrawable( Bitmap.createBitmap(bitm2, 0, 0, bitm2.getWidth(), bitm2.getHeight(), matrix, true) ); layers[1].setAlpha( 50);
LayerDrawable layerDraw = new LayerDrawable(layers);
super.setImageDrawable(layerDraw);
super.invalidate();
STATE = OVERLAY;
}
}
private void OverLay(View view , MotionEvent event) {
if ( STATE == UNKNOWN && event.getAction() == MotionEvent.ACTION_MOVE) {
STATE = OVERLAY;
if ( event.getX() > 1 && event.getX() < 1130 ) {
layers[1].setAlpha( (int) (event.getX() / 4.35f) );
}
}
}
private void AddPoints(View view , MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: touch_start(event.getX() , event.getY()); break;
case MotionEvent.ACTION_MOVE: touch_busy (event.getX() , event.getY()); break;
case MotionEvent.ACTION_UP: touch_end (event.getX() , event.getY()); break;
}
}
private void touch_start(float x, float y) {
STATE = STARTING;
touch_counter++;
busy.x = ((x - 32.0f + (float)getScrollX()));
busy.y = ((y - 70.0f + (float)getScrollY()));
}
private void touch_busy(float x, float y) {
busy.x = ((x - 32.0f + (float)getScrollX()));
busy.y = ((y - 70.0f + (float)getScrollY()));
STATE = DRAGGING;
}
private void touch_end(float x, float y) {
STATE = MARKING;
if (touch_counter == 1) {
pointA = new PointF();
pointA.x = ((x - 32.0f)); // + ViewOffset.x));
pointA.y = ((y - 70.0f)); // + ViewOffset.y));
} else if (touch_counter == 2) {
pointB = new PointF();
pointB.x = ((x - 32.0f));
pointB.y = ((y - 70.0f));
if (CURRENT_STATUS == "DRAW_LINE") touch_counter = 0;
Log.i("Image" , "At this Point Calling Draw ");
super.draw(busyCanvas);
}
}
public myImage(Context context , FrameLayout screen) {
super(context);
super.setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF0000FF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(5);
STATE = IMG_INIT;
invalidate();
}
public void freeImage() {
try {
mBitmap.recycle();
tracking.recycle();
} catch (Exception err) {
ImageExceptionHandler(err);
}
}
@Override
public void setImageBitmap(Bitmap bmp) {
try {
STATE = SET_IMAGE;
busyCanvas = new Canvas();
busyCanvas.setBitmap(bmp);
mBitmap = bmp;
busyCanvas.setBitmap(bmp);
} catch (Exception err) {
ImageExceptionHandler(err);
}
super.setImageBitmap(bmp);
}
private void ImageExceptionHandler(Exception err) {
Log.e("image" , "==============================================");
Log.e("image" , "EXCEPTION Handling ");
Log.e("image" , "==============================================");
err.printStackTrace();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (CURRENT_STATUS == "PAN & ZOOM" ) ScrollAndZoom(v , event);
else if (CURRENT_STATUS == "OVERLAY" ) OverLay(v , event);
else if (CURRENT_STATUS == "DRAW_LINE" ) AddPoints(v , event);
else {
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
}
return true;
}
public void init() {
super.setScaleType( ImageView.ScaleType.MATRIX );
mode = NONE;
matrix = new Matrix();
matrix.set(getImageMatrix());
savematrix = new Matrix();
start = new PointF();
mid = new PointF();
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i("Image" , "Size Changed ["+w+"] x ["+h+"] ["+oldw+"] x ["+oldh+"] ");
super.onSizeChanged(w, h, oldw, oldh);
}
private static final short NONE = 0;
private static final short ZOOM = 1;
private static final short DRAG = 2;
private Matrix matrix = new Matrix();
private Matrix savematrix = new Matrix();
private short mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private float oldfactor = 1f;
private float factor = 1f;
private void ScrollAndZoom(View view , MotionEvent event) {
STATE = ZOOM_PAN;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: start.set(event.getX() , event.getY());
savematrix.set(matrix);
mode = DRAG;
break;
//------------------------------------------------
case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event);
midPoint(mid , event);
mode = ZOOM;
oldfactor = factor;
break;
//------------------------------------------------
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: start = new PointF();
mode = NONE;
matrix.set(getImageMatrix());
setBackgroundColor(Color.BLACK);
break;
//------------------------------------------------
case MotionEvent.ACTION_MOVE: matrix.set(savematrix);
if (mode == DRAG) {
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
setBackgroundColor(Color.BLACK);
matrix.postTranslate(dx, dy);
setImageMatrix(matrix);
} else if (mode == ZOOM) {
float newD = spacing(event);
float newfactor = newD / oldDist;
factor = oldfactor * newfactor;
zoom(newfactor);
}
break;
//------------------------------------------------
}
}
private void zoom (Float scale) {
setBackgroundColor(Color.BLACK);
matrix.postScale(scale , scale , mid.x , mid.y);
setImageMatrix(matrix);
}
private float spacing(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx*dx + dy*dy);
}
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 / 2f , y / 2f);
}
}
向前推进一些步骤 我已经重写了一些它现在将绘制线条并使用线条缩放来缩放整个图像。
但是,如果我画一条线,那么放大好!
但是当我再次绘制时,它会绘制一个Ultra放大的线条,当你缩小时,大部分图像现在都会丢失? ?和想法为什么?
提前致谢
这是当前的代码
public class myImage extends ImageView implements OnTouchListener {
private static final short NONE = 0;
private static final short ZOOM = 1;
private static final short DRAG = 2;
private static short mode = NONE;
private static PointF pointA = null;
private static PointF pointB = null;
private ImageView pointer = null;
private PointF busy = new PointF();
private PointF start = new PointF();
private PointF mid = new PointF();
private Matrix matrix = new Matrix();
private Matrix savematrix = new Matrix();
private Bitmap tracking = BitmapFactory.decodeResource(getResources(), R.drawable.target);
private Drawable[] layers = new Drawable[2];
private Bitmap mBitmap;
private Canvas mCanvas;
private Paint mPaint;
private int touch_counter = 0;
private long touchTime = -1;
private float oldDist = 1f;
private float oldfactor = 1f;
private float factor = 1f;
public myImage(Context context , FrameLayout screen) {
super(context);
super.setLayerType(LAYER_TYPE_HARDWARE, null);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF0000FF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(2);
mPaint.setTextSize(20f);
super.setScaleType( ImageView.ScaleType.MATRIX );
mode = NONE;
matrix = new Matrix();
matrix.set(getImageMatrix());
savematrix = new Matrix();
start = new PointF();
mid = new PointF();
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
}
public void freeImage() {
try {
mBitmap.recycle();
tracking.recycle();
} catch (Exception err) {
ImageExceptionHandler(err);
}
}
@Override
public void setImageBitmap(Bitmap bmp) {
try {
mBitmap = bmp;
mCanvas = new Canvas(bmp);
mCanvas.setBitmap(bmp);
} catch (Exception err) {
ImageExceptionHandler(err);
}
super.setImageBitmap(bmp);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if ( CURRENT_STATUS == "PAN & ZOOM" ) ScrollAndZoom(v , event);
else if ( CURRENT_STATUS == "DRAW_LINE" ) AddPoints(v , event);
else {
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
Log.w("ERROR" , "Should Never Be Here myImage On Touch ["+eedsActivity.CURRENT_STATUS+"] ");
Log.w("ERROR" , "Should Never Be Here myImage On Touch ["+eedsActivity.CURRENT_IMAGE +"] ");
Log.w("ERROR" , "Should Never Be Here myImage On Touch");
}
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.i("Image" , "Size Changed ["+w+"] x ["+h+"] ["+oldw+"] x ["+oldh+"] ");
super.onSizeChanged(w, h, oldw, oldh);
}
private void myDrawLine(PointF ptA , PointF ptB) {
mCanvas.drawBitmap(mBitmap , matrix , mPaint);
mPaint.setColor(Color.BLUE);
mCanvas.drawLine( ptA.x , ptA.y , ptB.x , ptB.y , mPaint);
if (ptA.x <= ptB.x ) mCanvas.translate( (ptA.x + 0.0f), (ptA.y + 0.0f) );
else mCanvas.translate( (ptA.x + 0.0f), (ptA.y + 0.0f) );
line newLine = new line(ptA , ptB , factor);
switch (newLine.getQuadrant()) {
case 1: mCanvas.rotate( (float) newLine.getAngle() ); break;
case 2: mCanvas.rotate( (newLine.getAngle() - 180.0f) ); break;
case 3: mCanvas.rotate( (newLine.getAngle() + 180.0f) ); break;
case 4: mCanvas.rotate( (float) newLine.getAngle() ); break;
}
String result = "";
mPaint.setColor(Color.YELLOW);
result = String.format("%4.3f mm", newLine.getDistance() );
mCanvas.drawText( result, ((newLine.getDistance() * line.PX_TO_MM) / 3.0f), -6.0f, mPaint);
invalidate();
}
public void recenter() {
oldDist = 1f;
oldfactor = 1f;
factor = 1f;
setBackgroundColor(Color.BLACK);
matrix.setScale(1f, 1f);
matrix.postTranslate(0f , 0f);
setImageMatrix(matrix);
}
private void AddPoints(View view , MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: touch_start(event.getX() , event.getY()); break;
case MotionEvent.ACTION_MOVE: touch_busy (event.getX() , event.getY()); break;
case MotionEvent.ACTION_UP: touch_end (event.getX() , event.getY()); break;
}
}
private void touch_start(float x, float y) {
touch_counter++;
busy.x = (x - 32.0f);
busy.y = (y - 70.0f);
LayoutParams lp = new LayoutParams(32 , 32);
pointer = new ImageView(super.getContext());
pointer.setBackgroundDrawable(getResources().getDrawable(R.drawable.target2));
lp.leftMargin = (int) x;
lp.topMargin = (int) y;
((ViewGroup) super.getParent()).addView(pointer , lp);
}
private void touch_busy(float x, float y) {
busy.x = (x - 32.0f);
busy.y = (y - 70.0f);
if (pointer != null) {
pointer.setLeft( (int)busy.x ); pointer.setRight ( (int)(busy.x+32) );
pointer.setTop ( (int)busy.y ); pointer.setBottom( (int)(busy.y+32) );
}
}
private void touch_end(float x, float y) {
((ViewGroup) super.getParent()).removeView(pointer);
if (touch_counter == 1) {
pointA = new PointF();
pointA.x = ((x - 32.0f));
pointA.y = ((y - 70.0f));
} else if (touch_counter == 2) {
pointB = new PointF();
pointB.x = ((x - 32.0f));
pointB.y = ((y - 70.0f));
}
if (touch_counter == 2) {
myDrawLine(pointA , pointB);
pointA = null; pointB = null;
pointC = null; touch_counter = 0;
}
}
private void ScrollAndZoom(View view , MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: if ((System.currentTimeMillis() - touchTime) < 400) {
// Double Click
touchTime = -1;
setBackgroundColor(Color.BLACK);
matrix.setScale(1f, 1f);
matrix.postTranslate(0f , 0f);
setImageMatrix(matrix);
} else {
// Single Click
touchTime = System.currentTimeMillis();
start.set(event.getX() , event.getY());
savematrix.set(matrix);
mode = DRAG;
}
break;
//------------------------------------------------
case MotionEvent.ACTION_POINTER_DOWN: touchTime = -1;
oldDist = distance(event);
midPoint(mid , event);
mode = ZOOM;
oldfactor = factor;
break;
//------------------------------------------------
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP: start = new PointF();
mode = NONE;
matrix.set(getImageMatrix());
setBackgroundColor(Color.BLACK);
break;
//------------------------------------------------
case MotionEvent.ACTION_MOVE: matrix.set(savematrix);
if (mode == DRAG) {
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
setBackgroundColor(Color.BLACK);
matrix.postTranslate(dx, dy);
setImageMatrix(matrix);
} else if (mode == ZOOM) {
float newD = distance(event);
float newfactor = newD / oldDist;
factor = oldfactor * newfactor;
setBackgroundColor(Color.BLACK);
matrix.postScale(newfactor , newfactor , mid.x , mid.y);
setImageMatrix(matrix);
}
break;
//------------------------------------------------
}
}
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx*dx + dy*dy);
}
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 / 2f , y / 2f);
}
private void ImageExceptionHandler(Exception err) {
Log.e("image" , "==============================================");
Log.e("image" , "EXCEPTION Handling ");
Log.e("image" , "==============================================");
err.printStackTrace();
}
}
答案 0 :(得分:1)
我认为pointB
总是为空,因为每个手势只能获得一个ACTION_DOWN
。当第一根手指向下时,你会得到动作,并触发touch_start()
,将touch_counter
设置为1.当第二根手指向下时,它不会,因为你得到{{1}而不是,没有检查。
假设你想要一个双指手势。如果它意味着“触摸此处然后触摸那里”,那么您不应该将每个ACTION_POINTER_DOWN
设置为touch_counter
为零。
答案 1 :(得分:0)
只有当STATE为'MARKING'时才会绘制您的线;在onDraw结束时,你将状态设置回UNKNOWN,它调用基类的onDraw但不绘制你的行。如果你想让你的线在其他状态下保持不变,你每次调用onDraw时都必须重新绘制它。