我有一个Android的绘图应用程序,我目前正在尝试添加一个真正的橡皮擦.在此之前,我刚刚使用白色涂料作为橡皮擦,但现在我不再使用背景颜色和图像了.我通过透明画布下方的图像视图来完成此操作.
我面临的问题是每当我启用我的橡皮擦时,它会在我用手指向下时画出一条坚实的黑色痕迹,但是一旦我释放它就会变成透明的.请参见下面的屏幕截图:
这是我的手指在屏幕上时的样子 - 一条坚实的黑色小道

这是我从屏幕上移开手指后的样子

所以,我似乎越来越接近了,但是当我的手指在擦除时触摸时,我无法找到正确的设置组合以避免黑色痕迹.以下是一些相关的代码片段:
的onDraw
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
canvas.drawPath(mPreviewPath, mPaint);
}
Run Code Online (Sandbox Code Playgroud)
的onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
float currentX = event.getX();
float currentY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchStart(currentX, currentY);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touchMove(currentX, currentY);
invalidate();
break;
case MotionEvent.ACTION_UP:
touchUp(currentX, currentY);
invalidate();
break;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
当前尝试橡皮擦设置
public void startEraser() {
mPaint.setAlpha(0);
mColor = Color.TRANSPARENT;
mPaint.setColor(Color.TRANSPARENT);
mPaint.setStrokeWidth(mBrushSize);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setMaskFilter(null);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaint.setAntiAlias(true); …Run Code Online (Sandbox Code Playgroud) 有一个关于通过 flutter ( YouTube )创建绘图应用程序的视频,该应用程序支持在用户点击屏幕时绘制线条/点,但我找不到一种功能/方法来擦除用户绘制的内容,例如 Android 原生(例如此处)对于线。我不能只是在它们上面覆盖一些像白色这样的颜色,因为我在手势检测器下面有背景图像。
有人可以给我一些建议吗?
我的示例项目:
import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends …Run Code Online (Sandbox Code Playgroud) 我搜索了这个问题并提出了各种解决方案.
但是,没有一个对我有用.
我在应用程序中有一个绘图画布.
画布的背景设置为活动中的png图像,该图像使用自定义视图(drawView);
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.containsKey("background")) {
//set the background to the resource in the extras
int imageResource = intent.getIntExtra("background",-1);
Drawable image = getResources().getDrawable(imageResource);
drawView.setBackground(image);
}
}
Run Code Online (Sandbox Code Playgroud)
在DrawingView类(drawview是实例)中,我存储了PathPaints集合中绘制的路径,它具有3个属性(路径,使用的绘制以及是否为橡皮擦);
private ArrayList<PathPaint> paths = new ArrayList<PathPaint>();
Run Code Online (Sandbox Code Playgroud)
然后我尝试在OnDraw中循环遍历这些路径,并每次使用它们绘制的颜料(多种颜色)重绘它们;
protected void onDraw(Canvas canvas) {
//if the drawing is new - dont draw any paths
if (isNew != true) {
//go through every previous path and draw them
for (PathPaint p : paths) {
if (!p.isErase) …Run Code Online (Sandbox Code Playgroud) 我一直在到处寻找一个被问过很多次的问题的答案。我花了几个小时浏览 SO 和 Google。必须有一个不需要费力搬山的答案。
我正在开发矢量绘图应用程序,最终使绘图和撤消功能正常工作。现在我需要一个橡皮擦:-o
编辑:根据@DonMag 的精彩文章,我能够非常接近橡皮擦,但仍然有些不对劲。因此,我将尝试解释我的视图和图层在应用程序中的位置以及我这样做的原因:
从底部视图/层开始到顶部......
BackgroundImageView - 我使用这个图像视图来保存绘图表面的“背景”。它是一个可以更改的层,可以保存和调用新的“模板”。我把它分开,这样用户就不能擦除绘图表面。背景由 CAShapeLayers 组成,用于表示不同的纸张类型。
MainImageView - 我使用这个图像视图来完成用户启动的所有绘图。所以我触摸并拖动我的手指,新的 CAShapeLayer 被添加到图像视图中。这使用户的绘图与“绘图表面”分开。这也是我希望擦除发生的地方
PageImagesView - 我使用这个视图来保存用户可以添加到页面的图像,并移动/调整它们的大小。我不希望橡皮擦影响图像,但是如果 MainImageView 中绘制的一条线穿过图像并需要擦除,它应该让图像显示出来,而不是删除图像的某些部分。
我还添加了另一个图层,试图让橡皮擦工作,并将其称为“EraserImageView”,并将“蒙版”绘制到其中,然后尝试将该蒙版应用于 MainImageView。
这是我的绘图代码,每次调用 touchesMoved 时都会调用:
编辑: 将橡皮擦代码添加到我的绘图代码中。
if eraser {
let linePath = UIBezierPath()
for (index, point) in line.enumerated() {
if index == 0 {
midPoint = CGPoint(
x: (point.x + point.x) / 2,
y: (point.y + point.y) / 2
)
linePath.move(to: midPoint!)
} else {
midPoint = CGPoint(
x: (point.x + line[index - 1].x) / …Run Code Online (Sandbox Code Playgroud)