0

元に戻す/やり直し機能を備えたペイントアプリに取り組んでおり、消しゴム機能を追加したいと考えています。

MainActivity のコード

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();
   } 

質問:

通常の塗装と元に戻す・やり直しがバッチリ出来ます。ただし、消しゴムは使えません。

  1. 消しゴムボタン( touch_start) を押して画面にタッチすると、直前に描いた線がすべてすぐに黒くなります。

  2. で消しゴムを使用すると、モードtouch_moveがオンになっているにもかかわらず、消しゴム自体が黒い線を描画しCLEARます。

  3. の場合、他のすべての描画touch_upされた線は黒色に維持されます。「消された」領域も黒色でした。ただし、後で新しいパスを描画すると、元の線は元の色に変わり、消しゴムによって「消去」された領域はその色が最後に選択された色になり、パスはビューに保持されます。

消しゴムのコードはどのように適切な方法で書くことができますか? (元に戻す/やり直しを維持)

よろしくお願いします!

4

4 に答える 4

0

このタイプのアプリケーションを samsung spen sdk で試してみてください。この機能はすべて簡略化されています。 SPen SDK チュートリアル

また

消去ペイントの色を背景色にします。

于 2014-11-07T06:49:00.107 に答える
0

// これは消去の概念です。これは動作し、テストされています。

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();
        }
    }
于 2014-11-07T07:52:39.500 に答える