Android 旋转时在画布上以相反方向绘制路径
您好,我正在擦除使用触摸(手指)在画布上绘制的位图,工作正常。我面临的问题是在画布路径上旋转位图后以相反方向绘制表示位图以手指触摸的相反方向擦除 绘图窗格类Android 旋转时在画布上以相反方向绘制路径,android,android-canvas,eraser,Android,Android Canvas,Eraser,您好,我正在擦除使用触摸(手指)在画布上绘制的位图,工作正常。我面临的问题是在画布路径上旋转位图后以相反方向绘制表示位图以手指触摸的相反方向擦除 绘图窗格类 public class DrawingPanel extends ImageView implements OnTouchListener { private Matrix mMatrix = new Matrix(); private float mScaleFactor = 1f; private float mRotationD
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;
}
}
}
公共类DrawingPanel扩展了ImageView实现到TouchListener{
私有矩阵mMatrix=新矩阵();
私人浮动mScaleFactor=1f;
私有浮动mRotationDegrees=0.f;
专用浮点mFocusX=0.f;
专用浮点数mFocusY=0.f;
私有int-mAlpha=255;
私有int mImageHeight、mImageWidth;
专用scalegestruedetector mScaleDetector;
专用旋转检测器;
私人移动运动检测器;
专用铲运机探测器mShoveDetector;
私有布尔isMoving=false;
编辑光活性编辑活性;
位图叠加故障;
位图叠加;
位图bmp,bmp2;
油漆涂刷;
所选的int=0;
专用路径mPath;
显示;
私有ArrayList路径=新ArrayList();
private ArrayList xlist=新的ArrayList();
private ArrayList ylist=new ArrayList();
@SuppressLint(“新API”)
公共绘图面板(上下文、int-colorPaint、位图bmp){
超级(上下文);
如果(Build.VERSION.SDK_INT>=11){
setLayerType(View.LAYER\u TYPE\u硬件,空);
}
显示=((活动)上下文).getWindowManager().getDefaultDisplay();
mFocusX=display.getWidth()/2f;
mFocusY=display.getHeight()/2f;
试一试{
叠加故障=bmp;
叠加=bmp;
overlay=overlay.copy(Config.ARGB_8888,true);
覆盖。setHasAlpha(真);
}捕获(例外e){
e、 printStackTrace();
}
mImageHeight=getHeight();
mImageWidth=getWidth();
//设置手势检测器
mScaleDetector=新的scalegestruedetector(上下文,新的ScaleListener());
mRotateDetector=newrotategesturedetector(上下文,newrotatelistener());
mMoveDetector=newMoveGestureDetector(上下文,newMoveListener());
mShoveDetector=新的ShewGestureDetector(上下文,新的ShewListener());
pTouch=新油漆(油漆.防油漆别名标志);
pTouch.setXfermode(新的PorterDuffXfermode(Mode.CLEAR));
pTouch.setColor(颜色.透明);
//pTouch.setMaskFilter(新的BlurMaskFilter(30,Blur.SOLID));
pTouch.setStyle(油漆、样式、笔划);
pTouch.setStrokeJoin(油漆.连接.圆形);
pTouch.setStrokeCap(油漆盖圆形);
p设定行程宽度(50);
pTouch.setantialas(真);
设置聚焦(真);
setFocusableInTouchMode(真);
mPath=新路径();
路径。添加(mPath);
}
@凌驾
已更改尺寸的受保护空心(整数w、整数h、整数oldw、整数oldh){
super.onSizeChanged(w,h,oldw,oldh);
mImageHeight=getHeight();
mImageWidth=getWidth();
bmp=Bitmap.createScaledBitmap(叠加,w,h,false);
bmp2=Bitmap.createScaledBitmap(overlayDefault,w,h,false);
overlay=bmp.copy(Config.ARGB_8888,true);
overlayDefault=bmp2.copy(Config.ARGB_8888,true);
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
//TODO自动生成的方法存根
超级测量(宽度测量、高度测量);
设置测量尺寸(宽度测量等级、高度测量等级);
}
@凌驾
受保护的void onDraw(画布){
//drawBitmap(overlayDefault,0,0,null);//排除此行以在绘制时显示所有内容
//麦肯瓦斯拉丝圈(X,Y,80,pTouch);
//在背景上绘制覆盖图
浮动比例图像中心X=(mImageWidth*mScaleFactor)/2;
浮动比例图像中心=(mImageHeight*mScaleFactor)/2;
mMatrix.reset();
mMatrix.后量表(mScaleFactor,mScaleFactor);
mMatrix.postRotate(mRotationDegrees、scaledImageCenterX、scaledImageCenterY);
如果(正在移动)
{
mMatrix.postTranslate(mFocusX-scaledImageCenterX,mFocusY-scaledImageCenterY);
}
其他的
{
mMatrix.postTranslate(0,0);
}
canvas.setMatrix(mMatrix);
drawBitmap(覆盖,0,0,null);
用于(路径p:路径){
画布绘制路径(p,pTouch);
}
super.onDraw(帆布);
}
公共位图getBitmap(){
位图b=Bitmap.createScaledBitmap(覆盖,display.getWidth(),display.getWidth(),false);
overlay=b.copy(Config.ARGB_8888,true);
返回叠加;
}
公共void setBitmap(位图bmp1){
叠加=bmp1;
使无效();
}
私人浮动mX,我的;
专用静态最终浮动接触公差=0;
公共无效触摸启动(浮动x、浮动y){
if(xlist.size()>0&&ylist.size()>0){
xlist.clear();
ylist.clear();
}
xlist.add(x);
添加(y);
mPath.reset();
移动到(x,y)的速度;
mX=x;
mY=y;
变换(mMatrix,mPath);
使无效();
}
公共无效触摸移动(浮动x、浮动y){
float dx=Math.abs(x-mX);
float dy=Math.abs(y-mY);
如果(dx>=接触公差| | dy>=接触公差){
兆帕四分之一秒(mX,mY,(x+mX)/2,(y+mY)/2);
mX=x;
mY=y;
变换(mMatrix,mPath);
}
xlist.add(x);
添加(y);
使无效();
}
公共空间修补(){
mPath.lineTo(mX,mY);
mPath=新路径();
变换(mMatrix,mPath);
路径。添加(mPath);
使无效();
}
父对象上的公共无效(MotionEvent事件){
mScaleDetector.onTouchEvent(事件);
mRotateDetector.onTouchEvent(事件);
mMoveDetector.onTouchEvent(事件);
mShoveDetector.onTouchEvent(事件);
浮动比例图像中心X=(mImageWidth*mScaleFactor)/2;
浮动比例图像中心=(mImageHeight*mScaleFactor)/2;
mMatrix.reset();
mMatrix.后量表(mScaleFactor,mScaleFactor);
mMatrix.postRotate(mRotationDegrees、scaledImageCenterX、scaledImageCenterY);
mMatrix.postTranslate(mFocusX-scaledImageCenterX
canvas.save();
canvas.concat(mMatrix);
//write the code....
canvas.restore();
float[] coords = new float[] { event.getX(), event.getY() };
tempMatrix.mapPoints(coords);
float x = coords[0];//event.getX();
float y = coords[1];//event.getY();