安卓:用橡皮擦绘画应用程序无法正常工作

编程入门 行业动态 更新时间:2024-10-10 02:20:15
本文介绍了安卓:用橡皮擦绘画应用程序无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我工作的一幅画的应用程序,以撤销/重做功能,并想补充橡皮擦功能。

I am working on a painting app, with undo/redo function and would like to add eraser function.

case R.id.undoBtn: doodleView.onClickUndo(); break; case R.id.redoBtn: doodleView.onClickRedo(); break; case R.id.eraserBtn: Constants.mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); break;

DrawView

// Drawing Part private Bitmap mBitmap; private Paint mBitmapPaint; private Canvas mCanvas; private Path mPath; private int selectedColor = Color.BLACK; private int selectedWidth = 5; private ArrayList<Path> paths = new ArrayList<Path>(); private ArrayList<Path> undonePaths = new ArrayList<Path>(); private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>(); private Map<Path, Integer> widthMap = new HashMap<Path, Integer>(); private float mX, mY; private static final float TOUCH_TOLERANCE = 4; Context context_new; public DoodleView(Context c, AttributeSet attrs) { super(c, attrs); context_new = c; setFocusable(true); setFocusableInTouchMode(true); setLayerType(View.LAYER_TYPE_SOFTWARE, null); // for solely removing the black eraser mPath = new Path(); mCanvas = new Canvas(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); Constants.mPaint = new Paint(); Constants.mPaint.setAntiAlias(true); // smooth edges of drawn line Constants.mPaint.setDither(true); Constants.mPaint.setColor(Color.BLACK); // default color is black Constants.mPaint.setStyle(Paint.Style.STROKE); // solid line Constants.mPaint.setStrokeJoin(Paint.Join.ROUND); Constants.mPaint.setStrokeWidth(20); // set the default line width Constants.mPaint.setStrokeCap(Paint.Cap.ROUND); // rounded line ends Constants.mPaint.setXfermode(null); Constants.mPaint.setAlpha(0xFF); } @Override public void onSizeChanged(int w, int h, int oldW, int oldH) { super.onSizeChanged(w, h, oldW, oldH); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Constants.DRAW_W = w; Constants.DRAW_H = h; Log.d("TAG", "onSizeChanged!!!" + Constants.DRAW_W + Constants.DRAW_H + Constants.SCREEN_W + Constants.SCREEN_H); // bitmap.eraseColor(Color.WHITE); // erase the BitMap with white } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, null); // draw the background screen for (Path p : paths) { Constants.mPaint.setColor(colorsMap.get(p)); Constants.mPaint.setStrokeWidth(widthMap.get(p)); canvas.drawPath(p, Constants.mPaint); } Constants.mPaint.setColor(selectedColor); Constants.mPaint.setStrokeWidth(selectedWidth); canvas.drawPath(mPath, Constants.mPaint); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } private void touch_start(float x, float y) { undonePaths.clear(); mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private 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; startdrawing = true; } } private void touch_up() { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, Constants.mPaint); paths.add(mPath); colorsMap.put(mPath,selectedColor); widthMap.put(mPath,selectedWidth); mPath = new Path(); } public void onClickUndo() { if (paths.size()>0) { undonePaths.add(paths.remove(paths.size()-1)); invalidate(); } else Toast.makeText(getContext(), R.string.toast_nothing_to_undo, Toast.LENGTH_SHORT).show(); } public void onClickRedo() { if (undonePaths.size()>0) { paths.add(undonePaths.remove(undonePaths.size()-1)); invalidate(); } else Toast.makeText(getContext(), R.string.toast_nothing_to_redo, Toast.LENGTH_SHORT).show(); } public void setDrawingColor(int color) { selectedColor = color; Constants.mPaint.setColor(color); } public int getDrawingColor() { return Constants.mPaint.getColor(); }

问:

普通绘画和撤销/重做可以完美进行。然而,橡皮不起作用。

Question:

Normal painting and undo / redo can be performed perfectly. However, the eraser does not work.

  • 在pressing( touch_start )橡皮擦按钮,触摸屏幕,所有的previous画线立即变黑。

  • After pressing (touch_start) the eraser button and touch the screen, all the previous drawn line immediately turn black.

    在使用时 TOUCH_MOVE 橡皮擦,橡皮本身画黑线,即使它是在清除模式。

    When using the eraser upon touch_move , the eraser itself is drawing black lines, even though it was on CLEAR mode.

    当 touch_up ,维持在黑色的所有其他绘制的线条。在擦除区域也是在黑色。然而,随后绘制新路径时,原来的线转向到其原来的颜色,把它的颜色为上次选择的颜色,并保持在视野中的路径通过橡皮擦擦除的区域。

    Upon touch_up, All other drawn lines maintained at black color. The "erased" area was also in black color. However, when drawing a new path subsequently, the original line turned to their original color, the area "erased" by the eraser turn its color to the last color chosen and the paths retained in the View.

    如何能在橡皮code可以以适当的方式写的? (保持撤销/重做)

    How could the code on eraser be written in a proper way? (keeping undo / redo)

    非常感谢事先!

    推荐答案

    //请使用了消失的概念。这是工作和测试。

    // Please use this is erasure concept . This is working and tested.

    public void addErasure(){ drawView.setErase(true); drawView.setBrushSize(20); } public void addPencil(){ drawView.setErase(false); drawView.setBrushSize(20); drawView.setLastBrushSize(20); } /// this my drawing view. you can add this view into your main layout. public class DrawingView extends View { //drawing path private Path drawPath; //drawing and canvas paint private Paint drawPaint, canvasPaint; //initial color private int paintColor = 0xFF660000; //canvas private Canvas drawCanvas; //canvas bitmap private Bitmap canvasBitmap; //brush sizes private float brushSize, lastBrushSize; //erase flag private boolean erase=false; private boolean isFirstTime = false; public DrawingView(Context context, AttributeSet attrs){ super(context, attrs); //setBackgroundColor(Color.CYAN); setupDrawing(); } //setup drawing private void setupDrawing(){ //prepare for drawing and setup paint stroke properties brushSize = getResources().getInteger(R.integer.medium_size); lastBrushSize = brushSize; drawPath = new Path(); drawPaint = new Paint(); drawPaint.setColor(paintColor); drawPaint.setAntiAlias(true); drawPaint.setStrokeWidth(brushSize); drawPaint.setStyle(Paint.Style.STROKE); drawPaint.setStrokeJoin(Paint.Join.ROUND); drawPaint.setStrokeCap(Paint.Cap.ROUND); canvasPaint = new Paint(Paint.DITHER_FLAG); //canvasPaint.setColor(Color.GREEN); } //size assigned to view @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Bitmap canvasBackGroundBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); canvasBackGroundBitmap = getResizedBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.pop_up_big_bg),h,w); // drawCanvas = new Canvas(canvasBackGroundBitmap); // drawCanvas.drawColor(Color.GREEN); setBackgroundDrawable(new BitmapDrawable(canvasBackGroundBitmap)); drawCanvas = new Canvas(canvasBitmap); } public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) { int width = bm.getWidth(); int height = bm.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; // CREATE A MATRIX FOR THE MANIPULATION Matrix matrix = new Matrix(); // RESIZE THE BIT MAP matrix.postScale(scaleWidth, scaleHeight); // "RECREATE" THE NEW BITMAP Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false); return resizedBitmap; } //draw the view - will be called after touch event @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); canvas.drawPath(drawPath, drawPaint); } //register user touches as drawing action @Override public boolean onTouchEvent(MotionEvent event) { float touchX = event.getX(); float touchY = event.getY(); //respond to down, move and up events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: drawPath.moveTo(touchX, touchY); break; case MotionEvent.ACTION_MOVE: drawPath.lineTo(touchX, touchY); drawCanvas.drawPath(drawPath, drawPaint); drawPath.reset(); drawPath.moveTo(touchX, touchY); break; case MotionEvent.ACTION_UP: //drawPath.lineTo(touchX, touchY); //drawCanvas.drawPath(drawPath, drawPaint); drawPath.reset(); break; default: return false; } //redraw invalidate(); return true; } //update color public void setColor(String newColor){ invalidate(); paintColor = Color.parseColor(newColor); drawPaint.setColor(paintColor); } //set brush size public void setBrushSize(float newSize){ float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, newSize, getResources().getDisplayMetrics()); brushSize=pixelAmount; drawPaint.setStrokeWidth(brushSize); } //get and set last brush size public void setLastBrushSize(float lastSize){ lastBrushSize=lastSize; } public float getLastBrushSize(){ return lastBrushSize; } //set erase true or false public void setErase(boolean isErase){ erase=isErase; if(erase) { drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); }else { drawPaint.setXfermode(null); } } //start new drawing public void startNew(){ drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR); invalidate(); } }
  • 更多推荐

    安卓:用橡皮擦绘画应用程序无法正常工作

    本文发布于:2023-11-27 10:01:52,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1637612.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:橡皮擦   无法正常   应用程序   工作

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!