title: After fill color using floodfill algorithm, opacity of color is increase after drawing by finger on canvas
body: <p>I have canvas drawing app. I successfully done integrating floodfill algorithm for filling color for finger drawing circle and rectangle area. My problem is after filling color on finger drawing circle when i used blur mask brush effect and drawing using finger by blur mask brush then whole blur mask brush drawing is repaint again and again. Here is my code:</p>
  
  <pre><code>public class DrawingView extends View {
      private final Paint mDefaultPaint;
      Bitmap mBitmap;
      float x, y;
      ProgressDialog pd;
      LinearLayout drawing_layout;
      private Canvas mLayerCanvas = new Canvas();
      private Bitmap mLayerBitmap;
      final Point p1 = new Point();
      private Stack&lt;DrawOp&gt; mDrawOps = new Stack&lt;&gt;();
      private Stack&lt;DrawOp&gt; mUndoOps = new Stack&lt;&gt;();
  
      boolean isFill = false;
      private SparseArray&lt;DrawOp&gt; mCurrentOps = new SparseArray&lt;&gt;(0);
  
      public DrawingView(Context context) {
          this(context, null, 0);
  
      }
  
      public DrawingView(Context context, AttributeSet attrs) {
          this(context, attrs, 0);
      }
  
      public DrawingView(Context context, AttributeSet attrs, int defStyle) {
          super(context, attrs, defStyle);
  
          mDefaultPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          mDefaultPaint.setStyle(Paint.Style.STROKE);
          mDefaultPaint.setStrokeJoin(Paint.Join.ROUND);
          mDefaultPaint.setStrokeCap(Paint.Cap.ROUND);
          mDefaultPaint.setStrokeWidth(40);
          mDefaultPaint.setColor(Color.GREEN);
  
          setFocusable(true);
          setFocusableInTouchMode(true);
          setBackgroundColor(Color.WHITE);
  
          setLayerType(LAYER_TYPE_SOFTWARE, null);
          setSaveEnabled(true);
      }
  
      @Override
      public boolean onTouchEvent(@NonNull MotionEvent event) {
          final int pointerCount = MotionEventCompat.getPointerCount(event);
  
          switch (MotionEventCompat.getActionMasked(event)) {
          case MotionEvent.ACTION_DOWN: {
              if (isFill == true) {
  
                  int xx = (int) event.getX();
                  int yy = (int) event.getY();
                  Point pp = new Point(xx, yy);
  
                  /*Point pp = new Point();
                  pp.x = (int) event.getX();
                  pp.y = (int) event.getY();*/
  
                  final int sourceColor = mLayerBitmap.getPixel(xx, yy);
                  final int targetColor = mDefaultPaint.getColor();
  
                  new TheTask(mLayerBitmap, pp, sourceColor, targetColor)
                          .execute();
  
  //              JniBitmap.floodFill(mLayerBitmap, xx, yy, sourceColor,targetColor);
  
  /*              FloodFill f = new FloodFill();
                  f.floodFill(mLayerBitmap, pp, sourceColor, targetColor);*/
  
              }
              for (int p = 0; p &lt; pointerCount; p++) {
                  final int id = MotionEventCompat.getPointerId(event, p);
                  DrawOp current = new DrawOp(mDefaultPaint);
                  current.getPath().moveTo(event.getX(), event.getY());
                  mCurrentOps.put(id, current);
              }
          }
              break;
  
          case MotionEvent.ACTION_MOVE: {
  
                  if (isFill == false) {
  
                  final int id = MotionEventCompat.getPointerId(event, 0);
                  DrawOp current = mCurrentOps.get(id);
                  final int historySize = event.getHistorySize();
                  for (int h = 0; h &lt; historySize; h++) {
                      x = event.getHistoricalX(h);
                      y = event.getHistoricalY(h);
                      current.getPath().lineTo(x, y);
                  }
                  x = MotionEventCompat.getX(event, 0);
                  y = MotionEventCompat.getY(event, 0);
                  current.getPath().lineTo(x, y);
              }
          }
              break;
  
          case MotionEvent.ACTION_UP: {
              for (int p = 0; p &lt; pointerCount; p++) {
                  final int id = MotionEventCompat.getPointerId(event, p);
                  mDrawOps.push(mCurrentOps.get(id));
                  mCurrentOps.remove(id);
              }
              updateLayer();
          }
              break;
  
          case MotionEvent.ACTION_CANCEL: {
              for (int p = 0; p &lt; pointerCount; p++) {
                  mCurrentOps.remove(MotionEventCompat.getPointerId(event, p));
              }
              updateLayer();
          }
              break;
  
          default:
              return false;
          }
  
          invalidate();
          return true;
      }
  
      class TheTask extends AsyncTask&lt;Void, Integer, Void&gt; {
  
          Bitmap bmp;
          Point pt;
          int replacementColor, targetColor;
  
          public TheTask(Bitmap bm, Point p, int sc, int tc) {
  //          this.bmp = bm;
              mLayerBitmap = bm;
              pd = new ProgressDialog(getContext());
              this.pt = p;
              this.replacementColor = tc;
              this.targetColor = sc;
              pd.setMessage("Filling....");
              pd.show();
          }
  
          @Override
          protected void onPreExecute() {
          }
  
          @Override
          protected void onProgressUpdate(Integer... values) {
          }
  
          @Override
          protected Void doInBackground(Void... params) {
              FloodFill f = new FloodFill();
  //           mLayerBitmap = f.floodFill(bmp, pt, targetColor, replacementColor);
              f.floodFill(mLayerBitmap, pt, targetColor, replacementColor);
  
  //          New Commented Algorithm
  //          f.FloodFill(mLayerBitmap, pt, targetColor, replacementColor);
              return null;
          }
  
          @Override
          protected void onPostExecute(Void result) {
              pd.dismiss();
              invalidate();
              isFill = false;
          }
      }
  
      public void fillShapeColor(Bitmap mBitmap2) {
          isFill = true;
      }
  
      public void setDrawing() {
          isFill = false;
      }
  
      @Override
      protected void onSizeChanged(int w, int h, int oldW, int oldH) {
          super.onSizeChanged(w, h, oldW, oldH);
          mLayerBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
          mLayerCanvas.setBitmap(mLayerBitmap);
          updateLayer();
      }
  
      private void updateLayer() {
  
  
          for (DrawOp drawOp : mDrawOps) {
              if (drawOp != null) {
  //              drawOp.draw(new Canvas(mLayerBitmap));
                  drawOp.draw(mLayerCanvas);
              }
          }
          invalidate();
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
          super.onDraw(canvas);
  
          if (isInEditMode()) {
              return;
          }
          canvas.drawBitmap(mLayerBitmap, 0, 0, null);
  
          for (int i = 0; i &lt; mCurrentOps.size(); i++) {
              DrawOp current = mCurrentOps.valueAt(i);
              if (current != null) {
                  current.draw(canvas);
              }
          }
      }
  
      public void operationClear() {
          mDrawOps.clear();
          mUndoOps.clear();
          mCurrentOps.clear();
          // To Clear Whole Canvas
          mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
          updateLayer();
      }
  
      public void operationUndo() {
          if (mDrawOps.size() &gt; 0) {
              mUndoOps.push(mDrawOps.pop());
              updateLayer();
          }
      }
  
      public void operationRedo() {
          if (mUndoOps.size() &gt; 0) {
              mDrawOps.push(mUndoOps.pop());
              updateLayer();
          }
      }
  
      public void setPaintStrokeWidth(float widthPx) {
          mDefaultPaint.setStrokeWidth(widthPx);
      }
  
      /*public float getPaintStrokeWidth(){
          return mDefaultPaint.getStrokeWidth();
  
      }*/
  
      public void setPaintOpacity(int percent) {
          int alphaValue = (int) Math.round(percent * (255.0 / 100.0));
          mDefaultPaint.setColor(combineAlpha(mDefaultPaint.getColor(),
                  alphaValue));
      }
  
      /*public int getPaintOpacity(){
          this.setPaintOpacity(50);
          return mDefaultPaint.getColor();
      }*/
  
      public void setPaintColor(String color) {
          mDefaultPaint.setXfermode(null);
          mDefaultPaint.setColor(combineAlpha(Color.parseColor(color),
                  mDefaultPaint.getAlpha()));
  //      mDefaultPaint.setColor(mDefaultPaint.getAlpha());
      }
  
      public void setPaintColor(int color) {
          mDefaultPaint.setXfermode(null);
          mDefaultPaint.setColor(combineAlpha(color, mDefaultPaint.getAlpha()));
      }
  
  //  New Created
      public void setEraser(int color){
  //      mDefaultPaint.setAlpha(0xFF);
          mDefaultPaint.setColor(color);
          mDefaultPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
      }
  
      public void setPaintMaskFilter(MaskFilter filter) {
          mDefaultPaint.setMaskFilter(filter);
      }
  
      /*public MaskFilter getPaintMaskFilter(){
          return mDefaultPaint.getMaskFilter();
  
      }*/
  
      public void setPaintShader(BitmapShader shader) {
          mDefaultPaint.setShader(shader);
      }
  
      public void setPaintColorFilter(ColorFilter colorFilter) {
          mDefaultPaint.setColorFilter(colorFilter);
      }
  
      private static int combineAlpha(int color, int alpha) {
          return (color &amp; 0x00FFFFFF) | ((alpha &amp; 0xFF) &lt;&lt; 24);
      }
  
      private static class DrawOp {
          private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
          private final Path mPath = new Path();
  
          public DrawOp(Paint paint) {
              reset(paint);
          }
  
          void reset(Paint paint) {
              mPath.reset();
              update(paint);
          }
  
          void update(Paint paint) {
              mPaint.set(paint);
          }
  
          void draw(Canvas canvas) {
              canvas.drawPath(mPath, mPaint);
          }
  
          public Path getPath() {
              return mPath;
          }
      }
  }
  </code></pre>