嗨,我正在擦除用触摸(手指)在画布上绘制的位图,它工作正常我面临的问题是在画布路径上旋转位图后以相反方向绘制意味着位图擦除在我的手指触摸的相反方向上。
DrawingPane.class
public class DrawingPanel extends ImageView implements 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;
}
}
}