Опираясь на холст и объекты с несколькими красками

Я пытаюсь сделать приложение, в котором пользователь может либо выбрать размытие изображения, либо выбрать рисование на экране (пользователь может также сделать оба из них на одном холсте).

Тем не менее, у меня это довольно много работает, у меня возникает странная проблема с рисунком на первой жеребьевке после того, как режим изменился с размытия на краску или наоборот.

См. Изображение ниже.

РЕЖИМ КРАСКИ

Пути, нарисованные вертикально, – это когда пользователь выбрал режим рисования. Как вы видите, первый путь содержит краску как от объекта размытия, так и от объекта рисования (с красным штрихом). Любые последующие пути, нарисованные сейчас, отлично работают.

BLUR MODE

Аналогичным образом вы можете увидеть, после того, как вы рисуете два вертикальных пути, пользователь переключает режим на размытие и рисует горизонтальные дорожки в этом режиме. На этот раз, подобный вышеприведенному первому пути, представляет собой смесь двух объектов краски, и последующие пути работают нормально.

Пожалуйста, см. Код, размещенный ниже, и было бы здорово, если бы вы могли предложить, что может вызвать проблему.

Введите описание изображения здесь

ArrayList<DrawCommands> path_color_stroke_list = new ArrayList<DrawCommands>(); ArrayList<DrawCommands> path_color_stroke_list_undone = new ArrayList<DrawCommands>(); ArrayList<BlurCommands> path_blur_list = new ArrayList<BlurCommands>(); ArrayList<BlurCommands> path_blur_list_undone = new ArrayList<BlurCommands>(); ArrayList<EditTextDrawCommands> editTextList = new ArrayList<EditTextDrawCommands>(); private Bitmap mBitmap; private Paint transparentPaint; private Paint mPaint; public DrawingPanel(Context context, String imageStorageDir) { super(context); appContext = context; setFocusable(true); setFocusableInTouchMode(true); setClickable(true); this.setOnTouchListener(this); mPath = new Path(); setDefaultPaintAttributes(); BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inSampleSize = 8; blurRefImage = BitmapFactory.decodeResource(getResources(), R.drawable.canvas_test, bmOptions); canvasBackImage = BitmapFactory.decodeResource(getResources(), R.drawable.canvas_test); //stretch this small image to the size of the device so that it will be stretched and will already be blurred blurRefImage = Bitmap.createScaledBitmap(blurRefImage, Utilities.getDeviceWidth(), Utilities.getDeviceHeight(), true); blurRefImage = BlurBuilder.blurFullImage(appContext, blurRefImage, 20); mBitmap = Bitmap.createBitmap(Utilities.getDeviceWidth(), Utilities.getDeviceHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } protected void setDefaultPaintAttributes() { mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(30); //mPaint.setColor(0xcc000000); transparentPaint = new Paint(); transparentPaint.setStyle(Paint.Style.STROKE); transparentPaint.setStrokeJoin(Paint.Join.ROUND); transparentPaint.setStrokeCap(Paint.Cap.ROUND); transparentPaint.setStrokeWidth(60); transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } @Override protected void onDraw(Canvas canvas) { mCanvas.drawBitmap(canvasBackImage, 0, 0, mPaint); //Draw Blur for (BlurCommands path_blur : path_blur_list) { mCanvas.drawPath(path_blur.getPath(), transparentPaint); } //Draw Paints for (DrawCommands path_clr : path_color_stroke_list) { mCanvas.drawPath(path_clr.getPath(), mPaint); } switch (CURRENT_MODE) { case MODE_BLUR: mCanvas.drawPath(mPath, transparentPaint); break; case MODE_PAINT: mCanvas.drawPath(mPath, mPaint); break; } canvas.drawBitmap(blurRefImage, 0, 0, mPaint); canvas.drawBitmap(mBitmap, 0, 0, mPaint); } private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; switch (CURRENT_MODE) { case MODE_BLUR: break; case MODE_PAINT: break; default: break; } } 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) { switch (CURRENT_MODE) { case MODE_BLUR: case MODE_PAINT: mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; break; default: break; } } } private void touch_up(MotionEvent event) { switch (CURRENT_MODE) { case MODE_BLUR: mPath.lineTo(mX, mY); mPath = new Path(); path_blur_list.add(new BlurCommands(mPath, blurStrength, transparentPaint.getStrokeWidth())); break; case MODE_PAINT: mPath.lineTo(mX, mY); mPath = new Path(); path_color_stroke_list.add(new DrawCommands(mPath, mPaint.getColor(), mPaint.getStrokeWidth())); Log.d(TAG, "Touch up: X: " + mX + " Y: " + mY); break; default: break; } } 

Solutions Collecting From Web of "Опираясь на холст и объекты с несколькими красками"

Вероятно, вы захотите переключить порядок двух строк в touch_up, которые очищают путь (новый путь), и которые добавят объявление в список (сначала добавьте, затем очистите)

Ошибка возникает из-за того, что объект mPath создан в соответствии с предыдущим режимом рисования, поскольку он был создан с помощью мыши с предыдущим режимом рисования.

Переместите создание mPath в touch_start, и будет использоваться текущий режим рисования:

 private void touch_start(float x, float y) { mPath = new Path(); mPath.moveTo(x, y); mX = x; mY = y; switch (CURRENT_MODE) { case MODE_BLUR: path_blur_list.add(new BlurCommands(mPath, blurStrength, transparentPaint.getStrokeWidth())); break; case MODE_PAINT: path_color_stroke_list.add(new DrawCommands(mPath, mPaint.getColor(), mPaint.getStrokeWidth())); break; default: break; } } ... private void touch_up(MotionEvent event) { mPath.lineTo(mX, mY); }