测量两点之间

时间:2011-06-26 17:40:29

标签: android imageview

我已经创建了自己的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();
}
}

2 个答案:

答案 0 :(得分:1)

我认为pointB总是为空,因为每个手势只能获得一个ACTION_DOWN。当第一根手指向下时,你会得到动作,并触发touch_start(),将touch_counter设置为1.当第二根手指向下时,它不会,因为你得到{{1}而不是,没有检查。

假设你想要一个双指手势。如果它意味着“触摸此处然后触摸那里”,那么您不应该将每个ACTION_POINTER_DOWN设置为touch_counter为零。

答案 1 :(得分:0)

只有当STATE为'MARKING'时才会绘制您的线;在onDraw结束时,你将状态设置回UNKNOWN,它调用基类的onDraw但不绘制你的行。如果你想让你的线在其他状态下保持不变,你每次调用onDraw时都必须重新绘制它。