2013-05-14 193 views
4

我正在canvas.As下面的视图类使用缩放和画线。点击缩放按钮捏缩放工作fine.but当我点击油漆按钮我通过一个布尔值为true,在手指触摸上绘制线条。但是在图像上画线后,我想再次使用该图形线在图像的特定位置再次缩放缩放(使用拉线+图像1)Zoom Image缩放)2)with paint。 现在我想开始在图像2上缩放图像,如paint image.I试图搜索,但仍然没有任何成功。 感谢查看缩放和在画布上画线在Android

public class DemoView extends View { 

    private static final float STROKE_WIDTH = 5f; 

    /** Need to track this so the dirty region can accommodate the stroke. **/ 
    private static final float HALF_STROKE_WIDTH = STROKE_WIDTH/2; 

    private Paint paint = new Paint(); 
    private Path path = new Path(); 



    // These matrices will be used to move and zoom image 
     Matrix matrix = new Matrix(); 
     Matrix savedMatrix = new Matrix(); 

     // We can be in one of these 3 states 
     static final int NONE = 0; 
     static final int DRAG = 1; 
     static final int ZOOM = 0; 
     public static float xValue; 
     public static float yValue; 
     private static final float MAX_ZOOM = 10; 
     int mode = NONE; 

     // Remember some things for zooming 
     PointF start = new PointF(); 
     PointF mid = new PointF(); 
     float oldDist = 1f; 
     private float globalX; 
     private float globalY; 
     private float width; 
     private float height; 

    /** 
    * Optimizes painting by invalidating the smallest possible area. 
    */ 
    private float lastTouchX; 
    private float lastTouchY; 
    private final RectF dirtyRect = new RectF(); 

    private boolean flag; 

    private Bitmap bgBitmap; 
    private float mScaleFactor; 

    private int mActivePointerId; 

    private float mPosX; 

    private float mPosY; 

    public DemoView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     paint.setAntiAlias(true); 
     paint.setColor(Color.BLACK); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeJoin(Paint.Join.ROUND); 
     paint.setStrokeWidth(STROKE_WIDTH); 
     bgBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.nat); 
    } 
    @Override 
    public void draw(Canvas canvas) { 
     super.draw(canvas); 
     canvas.save(); 
     canvas.translate(mPosX, mPosY); 
     canvas.scale(mScaleFactor, mScaleFactor); 

     canvas.drawBitmap(bgBitmap, 0,0,null); 
     if(mScaleFactor != 1.f) 
      canvas.restore(); 

     if(flag) 
      canvas.drawPath(path,paint); 

     if(mScaleFactor == 1.f) 
      canvas.restore(); 
    } 

    /** 
    * Erases the signature. 
    */ 
    public void clear() { 
     path.reset(); 

     // Repaints the entire view. 
     invalidate(); 
    } 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     float eventX = event.getX(); 
     float eventY = event.getY(); 


     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      if (flag) { 
       path.moveTo(eventX, eventY); 
       lastTouchX = eventX; 
       lastTouchY = eventY; 
       // There is no end point yet, so don't waste cycles invalidating. 
       return true; 
      }else{ 
       savedMatrix.set(matrix); 
       start.set(event.getX(), event.getY()); 
       mode = DRAG; 
       mActivePointerId = event.getPointerId(0); 
       break; 
      } 

     case MotionEvent.ACTION_POINTER_DOWN: 
      oldDist = spacing(event); 
      if (oldDist > 10f) { 
       savedMatrix.set(matrix); 
       midPoint(mid, event); 
       mode = ZOOM; 
      } 
      break; 
     case MotionEvent.ACTION_POINTER_UP: 
      mode = NONE; 
      break; 
     case MotionEvent.ACTION_MOVE: 
     case MotionEvent.ACTION_UP: 
      if (flag) { 
       resetDirtyRect(eventX, eventY); 

       // When the hardware tracks events faster than they are delivered, 
       // the 
       // event will contain a history of those skipped points. 
       int historySize = event.getHistorySize(); 
       for (int i = 0; i < historySize; i++) { 
        float historicalX = event.getHistoricalX(i); 
        float historicalY = event.getHistoricalY(i); 
        expandDirtyRect(historicalX, historicalY); 
        path.lineTo(historicalX, historicalY); 
       } 

       // After replaying history, connect the line to the touch point. 
       path.lineTo(eventX, eventY); 
       break; 
      }else{ 
       // Start tracking the dirty region. 
       if (mode == DRAG) { 
        // ... 
        matrix.set(savedMatrix); 
        matrix.postTranslate(event.getX() - start.x, event.getY() 
          - start.y); 
       } else if (mode == ZOOM) { 
        float newDist = spacing(event); 
        if (newDist > 10f) { 
         matrix.set(savedMatrix); 
         float scale = newDist/oldDist; 
         matrix.postScale(scale, scale, mid.x, mid.y); 
        } 
//     final int pointerIndex = event.findPointerIndex((Integer) mActivePointerId); 
//     final float x = event.getX(pointerIndex); 
//     final float y = event.getY(pointerIndex); 
// 
//     final float dx = x - globalX; 
//     final float dy = y - globalY; 
//     mPosX += dx; 
//     mPosY += dy; 
       } 
      } 

     default: 
      Log.e("Ignored touch event: " ,"i"+ event.toString()); 
      return false; 
     } 

     // Include half the stroke width to avoid clipping. 
     invalidate((int) (dirtyRect.left - HALF_STROKE_WIDTH), 
       (int) (dirtyRect.top - HALF_STROKE_WIDTH), 
       (int) (dirtyRect.right + HALF_STROKE_WIDTH), 
       (int) (dirtyRect.bottom + HALF_STROKE_WIDTH)); 

     lastTouchX = eventX; 
     lastTouchY = eventY; 

     return true; 
    } 

    /** 
    * Called when replaying history to ensure the dirty region includes all 
    * points. 
    */ 
    private void expandDirtyRect(float historicalX, float historicalY) { 
     if (historicalX < dirtyRect.left) { 
      dirtyRect.left = historicalX; 
     } else if (historicalX > dirtyRect.right) { 
      dirtyRect.right = historicalX; 
     } 
     if (historicalY < dirtyRect.top) { 
      dirtyRect.top = historicalY; 
     } else if (historicalY > dirtyRect.bottom) { 
      dirtyRect.bottom = historicalY; 
     } 
    } 

    /** 
    * Resets the dirty region when the motion event occurs. 
    */ 
    private void resetDirtyRect(float eventX, float eventY) { 

     // The lastTouchX and lastTouchY were set when the ACTION_DOWN 
     // motion event occurred. 
     dirtyRect.left = Math.min(lastTouchX, eventX); 
     dirtyRect.right = Math.max(lastTouchX, eventX); 
     dirtyRect.top = Math.min(lastTouchY, eventY); 
     dirtyRect.bottom = Math.max(lastTouchY, eventY); 
    } 


    /** Determine the space between the first two fingers */ 
    private float spacing(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); 
    } 

    /** Calculate the mid point of the first two fingers */ 
    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/2, y/2); 
    } 

    public boolean setFlag(boolean b) { 
     return flag = b; 
    } 
} 
+1

转换从画布图像后搽一遍,然后做它的变焦。 – MKJParekh 2013-05-14 11:06:19

+0

@MKJParekh但是当我从画布转换图像,然后我只能得到图像的一部分不是整个图像:( – kyogs 2013-05-14 11:32:58

回答

1

用双指缩放图片和图像绘制。

imageView.setOnTouchListener(new OnTouchListener() { 
       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        ImageView view = (ImageView) v; 

        switch (event.getAction() & MotionEvent.ACTION_MASK) { 
        case MotionEvent.ACTION_DOWN: 
         savedMatrix.set(matrix1); 
         start.set(event.getX(), event.getY()); 
         mode = DRAG; 
         break; 
        case MotionEvent.ACTION_POINTER_DOWN: 
         oldDist = spacing(event); 
         if (oldDist > 10f) { 
          start.set(event.getX(), event.getY()); 
          savedMatrix.set(matrix1); 
          midPoint(mid, event); 
          // mode = POINT2; 
          mode = ZOOM; 
         } 
         break; 
        case MotionEvent.ACTION_UP: 
         mode = NONE; 
         distanceOffset = minOffset; 
        case MotionEvent.ACTION_POINTER_UP: 
         mode = NONE; 
         distanceOffset = minOffset; 
         break; 
        case MotionEvent.ACTION_MOVE: 
         if (mode == POINT2) { 
          newDist = spacing(event); 
          if (newDist - oldDist > 5f 
            || newDist - oldDist < -5f) { 
           mode = ZOOM; 
          } else { 
           start.set(event.getX(), event.getY()); 
           mode = DRAG; 
          } 
         } else if (mode == DRAG) { 
          matrix1.set(savedMatrix); 
          matrix1.postTranslate(event.getX() - start.x, 
            event.getY() - start.y); 
         } else if (mode == ZOOM) { 
          newDist = spacing(event); 
          if (newDist > 10f) { 
           matrix1.set(savedMatrix); 
           float scale = newDist/oldDist; 
           matrix1.postScale(scale, scale, mid.x, 
             mid.y); 
           finalscale = scale; 
          } 
         } 
         break; 
        } 

        view.setImageMatrix(matrix1); 
    //    matrixTurning(matrix1, view); 
        return true; // indicate event was handled 
       } 
      }); 
     } 



    mPaintView.setOnTouchListener(new OnTouchListener() { 

       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        PaintView view = (PaintView) v; 
        view.setScaleType(ImageView.ScaleType.MATRIX); 
        switch (event.getAction() & MotionEvent.ACTION_MASK) { 
        case MotionEvent.ACTION_DOWN: 
         if (falg) { 
          savedMatrix.set(matrix); 
          start.set(event.getX(), event.getY()); 
          mode = DRAG; 
         } else { 
          view.onTouchEvent(event); 
         } 
         break; 
        case MotionEvent.ACTION_POINTER_DOWN: 
         if (falg) { 
          oldDist = spacing(event); 
          if (oldDist > 10f) { 
           start.set(event.getX(), event.getY()); 
           savedMatrix.set(matrix); 
           midPoint(mid, event); 
           mode = ZOOM; 
          } 
         } 
         break; 
        case MotionEvent.ACTION_UP: 
         if (falg) { 
          mode = NONE; 
          distanceOffset = minOffset; 
         } 
        case MotionEvent.ACTION_POINTER_UP: 
         if (falg) { 
          mode = NONE; 
          distanceOffset = minOffset; 
         } 
         break; 
        case MotionEvent.ACTION_MOVE: 
         if (falg) { 
          if (mode == POINT2) { 
           newDist = spacing(event); 
           if (newDist - oldDist > 5f 
             || newDist - oldDist < -5f) { 
            mode = ZOOM; 
           } else { 
            start.set(event.getX(), event.getY()); 
            mode = DRAG; 
           } 
          } else if (mode == DRAG) { 
           matrix.set(savedMatrix); 
           matrix.postTranslate(event.getX() - start.x, 
             event.getY() - start.y); 
          } else if (mode == ZOOM) { 
           newDist = spacing(event); 
           if (newDist > 10f) { 
            matrix.set(savedMatrix); 
            float scale = newDist/oldDist; 
            matrix.postScale(scale, scale, mid.x, mid.y); 
            finalscale = scale; 
           } 
          } 
         } else { 
          view.onTouchEvent(event); 
         } 
         break; 
        } 

        limitZoom(matrix); 
        view.setImageMatrix(matrix); 

        matrixTurning(matrix, view); 
        RectF r = new RectF(); 
        matrix.mapRect(r); 
        scaledImageOffsetX = r.left; 
        scaledImageOffsetY = r.top; 

        return true; 
       } 
      }); 
     } 


     private void limitZoom(Matrix m) { 

      float[] values = new float[9]; 
      m.getValues(values); 
      float scaleX = values[Matrix.MSCALE_X]; 
      float scaleY = values[Matrix.MSCALE_Y]; 
      if(scaleX > MAX_ZOOM) { 
       scaleX = MAX_ZOOM; 
      } else if(scaleX < MIN_ZOOM) { 
       scaleX = MIN_ZOOM; 
      } 

      if(scaleY > MAX_ZOOM) { 
       scaleY = MAX_ZOOM; 
      } else if(scaleY < MIN_ZOOM) { 
       scaleY = MIN_ZOOM; 
      } 

      values[Matrix.MSCALE_X] = scaleX; 
      values[Matrix.MSCALE_Y] = scaleY; 
      m.setValues(values); 
     } 

     public boolean getFlag(boolean b) { 
      return falg = b; 
     } 

PaintView.class

class PaintView extends ImageView { 

private Bitmap mBitmap; 
private Canvas mCanvas; 
private Path mPath; 
private Paint mBitmapPaint; 

// onDraw 
private Paint mPaint; 

// onTouch 
private float mX, mY; 
private static final float TOUCH_TOLERANCE = 4; 

public PaintView(Context context) { 
    this(context, null); 
} 

public PaintView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    mBitmap = Bitmap.createBitmap(1024, 1024, Bitmap.Config.ARGB_8888); 
    mPath = new Path(); 
    mBitmapPaint = new Paint(Paint.DITHER_FLAG); 

} 

@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    // canvas.drawColor(0xFFAAAAAA); 
    super.onDraw(canvas); 
    mCanvas = canvas; 
    // canvas = mCanvas; 
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 
    // canvas.drawBitmap(mBitmap, PaintScreen.matrix, mBitmapPaint); 
    canvas.drawPath(mPath, mPaint); 

} 

public void clear() { 
    mPaint.reset(); 
    // invalidate(); 
} 

public void setMPaint(Paint paint) { 
    mPaint = paint; 
} 

private void touchStart(float x, float y) { 
    // mPath.reset(); 
    mPath.moveTo(x, y); 
    mX = x; 
    mY = y; 
} 

private void touchMove(float x, float y) { 
    float dx = Math.abs(x - mX); 
    float dy = Math.abs(y - mY); 
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
     mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); 
     mX = x; 
     mY = y; 
    } 
} 

private void touchUp() { 
    mPath.lineTo(mX, mY); 
    // commit the path to our offscreen 
    mCanvas.drawPath(mPath, mPaint); 
    // kill this so we don't double draw 
    mPath.reset(); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    float x = event.getX(); 
    float y = event.getY(); 

    Log.d("PaintView", "ev ->" + event.getAction()); 

    switch (event.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     touchStart(x, y); 
     invalidate(); 
     break; 
    case MotionEvent.ACTION_MOVE: 
     touchMove(x, y); 
     invalidate(); 
     break; 
    case MotionEvent.ACTION_UP: 
     touchUp(); 
     invalidate(); 
     break; 
    } 
    return true; 
} 

public void cMatrix(Matrix matrix) { 
    mCanvas.setMatrix(matrix); 
} 
} 
+0

如果可能的话,请提供完整的源代码,因为得到一些问题。 – 2014-11-26 13:27:53

+0

@kyogs请分享完整的源代码.. – MohsinSyd 2015-03-23 07:43:36

+0

@kyogs什么是matrixTurning(),spacing(),midPoint() – 2015-04-16 06:01:05