2014-12-31 2 views
0

enter image description here Привет, я стираю растровое изображение, которое нарисовано на холсте с прикосновением (пальцами), которое отлично работает, с проблемой, с которой я столкнулся, после поворота растрового изображения на холст-путях в направлении оппозиции среднее растровое стирание в оппозиционном направлении касания пальца.Путь рисовать в противоположном направлении на холсте при вращении андроида

общественного класса DrawingPanel расширяет ImageView реализует OnTouchListener {

private Matrix mMatrix = new Matrix(); 
private float mScaleFactor = 1f; 
private float mRotationDegrees = 0.f; 
private float mFocusX = 0.f; 
private float mFocusY = 0.f; 
private int mAlpha = 255; 
private int mImageHeight, mImageWidth; 

private ScaleGestureDetector mScaleDetector; 
private RotateGestureDetector mRotateDetector; 
private MoveGestureDetector mMoveDetector; 
private ShoveGestureDetector mShoveDetector; 
private boolean isMoving=false; 
EditPhotoActivity editActivity; 


Bitmap overlayDefault; 
Bitmap overlay; 
Bitmap bmp,bmp2; 
Paint pTouch; 

INT whichTabSelected = 0;

private Path mPath; 
Display display ; 
private ArrayList<Path> paths = new ArrayList<Path>(); 
private ArrayList<Float> xlist = new ArrayList<Float>(); 
private ArrayList<Float> ylist = new ArrayList<Float>(); 
@SuppressLint("NewApi") 
public DrawingPanel(Context context, int colorPaint,Bitmap bmp) { 
    super(context); 


    if (Build.VERSION.SDK_INT >= 11) { 
     setLayerType(View.LAYER_TYPE_HARDWARE, null); 
    } 
    display = ((Activity)context).getWindowManager().getDefaultDisplay(); 

    mFocusX = display.getWidth()/2f; 
    mFocusY = display.getHeight()/2f; 
    try { 

     overlayDefault=bmp; 
     overlay=bmp; 
     overlay=overlay.copy(Config.ARGB_8888, true); 
     overlay.setHasAlpha(true); 

    } catch (Exception e) { 

     e.printStackTrace(); 
    } 

    mImageHeight = getHeight(); 
    mImageWidth  = getWidth(); 


    // Setup Gesture Detectors 
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    mRotateDetector = new RotateGestureDetector(context, new RotateListener()); 
    mMoveDetector = new MoveGestureDetector(context, new MoveListener()); 
    mShoveDetector = new ShoveGestureDetector(context, new ShoveListener()); 


    pTouch = new Paint(Paint.ANTI_ALIAS_FLAG);   
    pTouch.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); 
    pTouch.setColor(Color.TRANSPARENT); 
    //pTouch.setMaskFilter(new BlurMaskFilter(30, Blur.SOLID)); 
    pTouch.setStyle(Paint.Style.STROKE); 
    pTouch.setStrokeJoin(Paint.Join.ROUND); 
    pTouch.setStrokeCap(Paint.Cap.ROUND); 
    pTouch.setStrokeWidth(50); 
    pTouch.setAntiAlias(true); 
    setFocusable(true); 
    setFocusableInTouchMode(true); 
    mPath = new Path(); 
    paths.add(mPath); 
} 


@Override 
protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
    super.onSizeChanged(w, h, oldw, oldh); 
    mImageHeight=getHeight(); 
    mImageWidth=getWidth(); 
    bmp = Bitmap.createScaledBitmap(overlay, w, h, false); 
    bmp2 = Bitmap.createScaledBitmap(overlayDefault, w, h, false); 
    overlay = bmp.copy(Config.ARGB_8888, true); 
    overlayDefault = bmp2.copy(Config.ARGB_8888, true); 

} 
@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // TODO Auto-generated method stub 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); 
} 

@Override 
protected void onDraw(Canvas canvas) { 

    // mCanvas.drawBitmap(overlayDefault,0, 0, null); //exclude this line to show all as you draw 

    // mCanvas.drawCircle(X, Y, 80, pTouch); 
    //draw the overlay over the background 

     float scaledImageCenterX = (mImageWidth*mScaleFactor)/2; 
     float scaledImageCenterY = (mImageHeight*mScaleFactor)/2; 
     mMatrix.reset(); 
     mMatrix.postScale(mScaleFactor, mScaleFactor); 
     mMatrix.postRotate(mRotationDegrees, scaledImageCenterX, scaledImageCenterY); 

     if(isMoving) 
     { 
      mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY - scaledImageCenterY); 
     } 
     else 
     { 
       mMatrix.postTranslate(0,0); 
     } 

     canvas.setMatrix(mMatrix); 

     canvas.drawBitmap(overlay,0,0, null); 

     for (Path p : paths) { 
      canvas.drawPath(p, pTouch); 
     } 
     super.onDraw(canvas); 
} 


public Bitmap getBitmap(){ 
    Bitmap b = Bitmap.createScaledBitmap(overlay,display.getWidth() ,display.getWidth(), false); 
    overlay = b.copy(Config.ARGB_8888, true); 
    return overlay; 
} 
public void setBitmap(Bitmap bmp1){ 
    overlay = bmp1; 

    invalidate(); 
} 
private float mX, mY; 
private static final float TOUCH_TOLERANCE = 0; 

public void touch_start(float x, float y) { 

    if(xlist.size()>0 && ylist.size()>0){ 
     xlist.clear(); 
     ylist.clear(); 
    } 
    xlist.add(x); 
    ylist.add(y); 
    mPath.reset(); 
    mPath.moveTo(x, y); 
    mX = x; 
    mY = y; 
    mPath.transform(mMatrix, mPath); 
    invalidate(); 
} 

public void touch_move(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; 
     mPath.transform(mMatrix, mPath); 
    } 
    xlist.add(x); 
    ylist.add(y); 
    invalidate(); 
} 

public void touch_up() { 
    mPath.lineTo(mX, mY); 

    mPath = new Path(); 
    mPath.transform(mMatrix, mPath); 
    paths.add(mPath); 
    invalidate(); 
} 


public void OnTouchParent(MotionEvent event){ 
    mScaleDetector.onTouchEvent(event); 
     mRotateDetector.onTouchEvent(event); 
     mMoveDetector.onTouchEvent(event); 
     mShoveDetector.onTouchEvent(event); 
     float scaledImageCenterX = (mImageWidth*mScaleFactor)/2; 
     float scaledImageCenterY = (mImageHeight*mScaleFactor)/2; 

     mMatrix.reset(); 
     mMatrix.postScale(mScaleFactor, mScaleFactor); 
     mMatrix.postRotate(mRotationDegrees, scaledImageCenterX, scaledImageCenterY); 
     mMatrix.postTranslate(mFocusX - scaledImageCenterX, mFocusY - scaledImageCenterY); 

     float x = event.getX(); 
     float y = event.getY(); 

     /*switch (event.getAction()) { 

     case MotionEvent.ACTION_DOWN: 
      if(whichTabSelected==Constant.ERASE) 
      { 
      touch_start(x, y); 
      invalidate(); 
      } 
      break; 

     case MotionEvent.ACTION_MOVE: 
      if(whichTabSelected==Constant.ERASE) 
      { 
      touch_move(x, y); 
      invalidate(); 
      } 
      break; 

     case MotionEvent.ACTION_UP: 
      if(whichTabSelected==Constant.ERASE) 
      { 
      touch_up(); 
      invalidate(); 
      } 
      break; 
     } 
     if(whichTabSelected==Constant.ERASE) 
     { 
     return true; 
     } 
     else 
     { 
      return false; 
     }*/ 

     invalidate(); 

} 
@Override 
public boolean onTouch(View arg0, MotionEvent event) { 


    if(getTabMode()==Constant.PANZOOM) 
    { 
    mScaleDetector.onTouchEvent(event); 
    mRotateDetector.onTouchEvent(event); 
    mMoveDetector.onTouchEvent(event); 
    mShoveDetector.onTouchEvent(event); 

    float scaledImageCenterX = (mImageWidth*mScaleFactor)/2; 
    float scaledImageCenterY = (mImageHeight*mScaleFactor)/2; 



    } 

    float x = event.getX(); 
    float y = event.getY(); 

    switch (event.getAction()) { 

    case MotionEvent.ACTION_DOWN: 
     if(getTabMode()==Constant.ERASE) 
     { 
     touch_start(x, y); 
     invalidate(); 
     } 
     break; 

    case MotionEvent.ACTION_MOVE: 
     if(getTabMode()==Constant.ERASE) 
     { 
     touch_move(x, y); 
     invalidate(); 
     } 
     break; 

    case MotionEvent.ACTION_UP: 
     if(getTabMode()==Constant.ERASE) 
     { 
     touch_up(); 
     invalidate(); 
     } 
     break; 
    } 


    invalidate(); 
    return true; 
} 
public void setBottomTabMode(int mode) 
{ 
    whichTabSelected=mode; 
} 
public int getTabMode() 
{ 
    return whichTabSelected; 
} 


private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
     mScaleFactor *= detector.getScaleFactor(); // scale change since previous event 

     // Don't let the object get too small or too large. 

     mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); 
     return true; 
    } 
} 

private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener { 
    @Override 
    public boolean onRotate(RotateGestureDetector detector) { 
     mRotationDegrees -= detector.getRotationDegreesDelta(); 
     return true; 
    } 
} 

private class MoveListener extends MoveGestureDetector.SimpleOnMoveGestureListener { 
    @Override 
    public boolean onMove(MoveGestureDetector detector) { 
     PointF d = detector.getFocusDelta(); 
     mFocusX += d.x; 
     mFocusY += d.y;  
     isMoving=true; 
     // mFocusX = detector.getFocusX(); 
     // mFocusY = detector.getFocusY(); 
     return true; 
    } 
}  

private class ShoveListener extends ShoveGestureDetector.SimpleOnShoveGestureListener { 
    @Override 
    public boolean onShove(ShoveGestureDetector detector) { 
     mAlpha += detector.getShovePixelsDelta(); 
     if (mAlpha > 255) 
      mAlpha = 255; 
     else if (mAlpha < 0) 
      mAlpha = 0; 

     return true; 
    } 
} 

}

+0

Не могли бы вы разместить изображение того, что вы получаете сейчас, и другое, что ожидается? –

+0

Итак, похоже, вы применили инвертированную матрицу к своим путям соответственно. Просто для подтверждения, если вы увеличиваете «цитату», уменьшена ли область стирания? –

+0

Да «область стирания» также масштабируется. –

ответ

1

Я зафиксировал мою проблему. Фактически, когда я поворачиваю холст, события.getX() и event.getY() не были привязаны к текущему вращению матрицы, поэтому добавив эту строку в mMatrix.invert (tempMatrix); в OnDraw(), а также отобразить текущий x, y в OnTouch(), добавив это в метод OnTouch().

float [] coords = new float [] {event.getX(), event.getY()};
tempMatrix.mapPoints (coords);

 float x = coords[0];//event.getX(); 
     float y = coords[1];//event.getY(); 

его рабочий тон.

0

Этот эффект происходит потому, что вы подаете матрицу дважды в пути.

Один раз в touch_start/touch_move делая mPath.transform(mMatrix, mPath);.

И снова в onDraw(Canvas canvas) от canvas.setMatrix(mMatrix);, а затем canvas.drawPath(p, pTouch);.

Чтобы исправить, попробуйте удалить mPath.transform(mMatrix, mPath); от touch_start/touch_move.

Кроме того, я не знаю, правильно ли установить матрицу непосредственно на холст. Вместо canvas.setMatrix(mMatrix);, я предпочел бы сделать следующее:

canvas.save(); 
    canvas.concat(mMatrix); 
    //write the code.... 
    canvas.restore(); 
+0

Теперь я удалил 'mPath.transform();' из 'touch_start/touch_move', а также заменил' canvas.setMatrix() 'на' canvas.concat() ', но результат тот же / –

Смежные вопросы