繁体   English   中英

在两点之间测量

[英]Measuring between two points

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

在我看来, pointB始终为null,因为每个手势只能获得一个ACTION_DOWN 当第一根手指放下时,您将获得操作,并触发touch_start() ,将touch_counter设置为1。第二根手指放下时,则不会,因为您得到了ACTION_POINTER_DOWN ,但未进行检查。

假设您要使用两指手势。 如果它的意思是“触摸此处,然后触摸有”代替,那么你不应该设置touch_counter为零每个touch_end()

仅当STATE为“ MARKING”时才绘制您的线; 在onDraw的最后,您将状态设置回UNKNOWN,这将调用基类的onDraw,但不会绘制线条。 如果您希望线在其他状态下停留,则每次调用onDraw时都必须重新绘制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM