2011-06-26 4 views
0

J'ai créé mon propre ImageView qui, je l'espère, fera des superpositions, zoom, panoramique et mesure entre deux points.Mesure entre deux points

Jusqu'ici tout sauf les travaux de mesure Le canvas.drawline ne montre rien?

Ceci peut être sale et pourrait probablement être nettoyé un peu. Quelqu'un at-il une idée pourquoi le canvas.drawline ne fonctionne pas?

Merci à l'avance

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); 
    } 



} 

Faire des progrès quelques pas en arrière j'ai réécrite certaines d'entre elles Il Puisez maintenant la ligne et un zoom sur l'image entière avec la ligne de zoom aussi. Cependant, si je dessine une ligne, puis Zoom avant! Mais lorsque je dessine à nouveau, il dessine la ligne d'un zoom avant, et lorsque vous faites un zoom arrière, la majeure partie de l'image est maintenant perdue? ? et des idées pourquoi?
Merci à l'avance

Voici le code actuel

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

Pouvez-vous définir un point d'arrêt sur canvas.drawLine et nous dire quelles sont les valeurs pour pointA et pointB? De plus, de quelle couleur est ton fond? –

+0

Merci, pointA est 132, 54 et pointB 334, 234 valeurs valides. Ma couleur de fond est noire (c'est derrière) le bitmap. et le bitmap est une règle jaune sur un bureau rouge bordeaux. J'ai mis dans les instructions Thread.sleep et il clignote sur l'écran et quand fait avec la fonction onDraw est effacé. donc il est là pour une fraction de seconde et ensuite parti. ainsi ils sont appelés mais ils sont effacés. – NewDev

Répondre

1

Il me semble que pointB est toujours nulle, parce que vous ne jamais obtenir un ACTION_DOWN par geste. Lorsque le premier doigt tombe en panne, vous obtenez l'action touch_start() et la valeur touch_counter à 1. Lorsque le deuxième doigt tombe, ce n'est pas le cas, car vous obtenez un ACTION_POINTER_DOWN à la place, ce qui n'est pas vérifié.

En supposant que vous voulez un geste à deux doigts. Si c'est censé être un 'toucher ici et ensuite toucher' à la place, alors vous ne devriez pas mettre touch_counter à zéro avec chaque touch_end().

+0

Il est d'utiliser un geste à deux doigts pour le zoom qui fonctionne. c'est utiliser le toucher ici et ensuite toucher le début et la fin de l'endroit où la ligne doit être. pointB devient une valeur Je reçois des valeurs correctes pour pointA et pointB mais la ligne n'est simplement pas dessinée/affichée? – NewDev

0

Votre ligne n'est dessinée que lorsque STATE est 'MARKING'; à la fin de onDraw, vous rétablissez votre état sur UNKNOWN, qui appelle l'onDraw de la classe de base, mais ne dessine pas votre ligne. Si vous voulez que votre ligne reste dans d'autres états, vous devrez la redessiner chaque fois que onDraw sera appelé.

+0

Merci à celui qui a corrigé la mise en page. Oui CURRENT_STATUS est défini par la mainActivity qui l'appelle et est défini sur DRAW_LINE oui – NewDev

Questions connexes