当前位置: 首页 > 知识库问答 >
问题:

创建一个带背景的钢笔/橡皮擦绘图应用程序。橡皮擦除背景图像,它应该只擦除笔

洪俊拔
2023-03-14

这是我的密码。现在钢笔绘图工作,橡皮擦绘图擦除,但它擦除背景图像。我只想让它擦去钢笔。

如果你能给我提示该怎么做,我将不胜感激。

===

//MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
public MyView myView;
boolean penOn;
boolean eraserOn;
Bitmap bMap;
private Canvas mCanvas;
private Canvas myForegroundCanvas;
private Path mPath;
private Bitmap mBitmap;
private Paint mPaint, mBitmapPaint;
private ArrayList<DrawAction> paths = new ArrayList<DrawAction>();
private ArrayList<DrawAction> undonePaths = new ArrayList<DrawAction>();
int selectedColor=Color.RED;
RelativeLayout container;
private int width;
private int height;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    View mainView = getLayoutInflater().inflate(R.layout.activity_main,
            null);

    myView = new MyView(this);
    container = (RelativeLayout) mainView.findViewById(R.id.container);
    container.addView(myView);

    setContentView(mainView);


    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(16);

    Button pen = (Button) mainView.findViewById(R.id.buttonpen);
    pen.setOnClickListener(this);
    Button eraser = (Button) mainView.findViewById(R.id.buttonerase);
    eraser.setOnClickListener(this);
    pen.bringToFront();
    eraser.bringToFront();

}




public class MyView extends View {

    public MyView(Context c) {
        super(c);

        if (android.os.Build.VERSION.SDK_INT >= 11) {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }

        DisplayMetrics displaymetrics = new DisplayMetrics();
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);

        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        MainActivity.this.width = size.x;
        MainActivity.this.height = size.y;

        bMap = getBitmapFromAsset(MainActivity.this, "google.png");
        Bitmap background = Bitmap.createScaledBitmap(bMap,
                MainActivity.this.width, MainActivity.this.height, false);

        mBitmap = background.copy(Bitmap.Config.ARGB_8888, true);


        mCanvas = new Canvas(mBitmap);

        myForegroundCanvas = new Canvas(mBitmap);

        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

    }


    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawColor(Color.TRANSPARENT);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        Paint textPaint = new Paint();
        textPaint.setTextSize(40);
        final Iterator<DrawAction> i = paths.iterator();
        while (i.hasNext()) {

            final DrawAction d = i.next();
            if (d.type.equals("pen")) {
                mPaint.setColor(d.color);
                mPaint.setXfermode(null);// clear the draw
                canvas.drawPath(d.path, mPaint);
                // myForegroundCanvas.drawPath(d.path, mPaint);

            } else if (d.type.equals("eraser")) {
                // mPaint.setAlpha(0xFF);//transperent color
                mPaint.setXfermode(new PorterDuffXfermode(
                        PorterDuff.Mode.CLEAR));// clear the draw
                canvas.drawPath(d.path, mPaint);
                // myForegroundCanvas.drawPath(d.path, mPaint);

            }


        }



        mPaint.setColor(selectedColor);
        canvas.drawPath(mPath, mPaint);
        // canvas.drawCanvas(myForegroundCanvas, 0, 0, null);

    }


    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

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

    private void touch_up() {

        mPath.lineTo(mX, mY);

        DrawAction d = new DrawAction(mPath, Color.RED);
        paths.add(d);

        mPath = new Path();
    }

    private void touch_start_eraser(float x, float y) {
        undonePaths.clear();
        mPaint.setColor(Color.WHITE);
        selectedColor=Color.WHITE;
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }

    private void touch_move_eraser(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;
        }
    }

    private void touch_up_eraser() {

        mPath.lineTo(mX, mY);

        DrawAction d = new DrawAction(mPath, true);
        paths.add(d);

        mPath = new Path();
    }



    @Override
    public boolean onTouchEvent(MotionEvent event) {

         if ( !penOn && eraserOn) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start_eraser(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move_eraser(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up_eraser();
                invalidate();
                break;
            }
            return true;
        } else {
            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;
        }
    }
}


public Bitmap getBitmapFromAsset(Context context, String strName) {
    AssetManager assetManager = context.getAssets();

    InputStream istr;
    Bitmap bitmap = null;
    try {
        istr = assetManager.open(strName);
        bitmap = BitmapFactory.decodeStream(istr);
    } catch (IOException e) {
        return null;
    }

    return bitmap;
}


@Override
public void onClick(View v) {

    switch (v.getId()) {
    case R.id.buttonpen:
        penOn=true;
        eraserOn=false;
        break;
    case R.id.buttonerase:
        penOn=false;
        eraserOn=true;
        break;

    }

}
    }
//DrawAction.java, a helper class for holding the path and what type of drawing to do (pen or erase)
public class DrawAction {
public String type;

public Path path;
public int color;

public DrawAction(final Path p, final int color) {
    this.type="pen";
    this.path=p;
    this.color=color;
}
public DrawAction(final Path p, final boolean isEraser) {
    this.type="eraser";
    this.path=p;
}
     }

====

//activity_main.xml the layout code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.doodle5.MainActivity"
tools:ignore="MergeRootFrame" >



    <Button
        android:id="@+id/buttonpen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="25dp"
        android:layout_marginRight="25dp"
        android:layout_marginTop="50dp"
        android:text="Pen" />

    <Button
        android:id="@+id/buttonerase"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="25dp"
        android:layout_marginTop="50dp"
        android:text="Erase" />
</RelativeLayout>

共有1个答案

华恩
2023-03-14

我想出来了。我最终将背景图像作为可绘制的背景放在容器上,而不是将其绘制到画布上。

在onDraw中,我注释掉了这一行:

canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

在onCreate中,我添加了:

BitmapDrawable ob = new BitmapDrawable(backgroundBitmap);
container.setBackgroundDrawable(ob);
 类似资料:
  • 我想使用Fabric.js在我的web应用程序中实现eraser。在Fabric.js中有没有实现橡皮擦的方法?例如,如在MS Paint?

  • 我正在一个绘画应用程序,与撤消/重做功能,并希望添加橡皮擦功能。 橡皮擦上的代码怎么写得合适?(保留撤消/重做) 提前多谢!

  • 我已经在谷歌上搜索了这个问题,并提出了各种解决方案。 但是,没有一个对我有效。 我在一个应用程序中有一个绘图画布。 画布的背景被设置为活动中的png图像,该活动使用自定义视图(drawView); 在DrawingView类(drawview是实例)中,我将绘制的路径存储在一个PathPaints集合中,该集合有3个属性(路径、使用的油漆以及如果是橡皮擦); 我已经尝试在drawpath上设置油漆

  • 绘画工具和绘画描边 笔刷工具 、仿制图章工具 和橡皮擦工具 都是绘画工具。您可以在“图层”面板中使用各个绘画工具将绘画描边应用于图层。每个绘画工具分别应用将修改图层区域的颜色或透明度而不修改图层源的笔刷笔迹。 每个绘画描边都有各自的持续时间条、“描边选项”属性和“变换”属性,您可以在“时间轴”面板中查看和修改这些属性。默认情况下,每个绘画描边均根据创建它的工具命名,并包含一个表示其绘制顺序的数字。

  • 我已经创建了一个HTML5绘图应用程序,它具有基本功能,允许用户选择一种颜色来绘制,改变绘图工具的大小(半径),撤消,重做,以及完全清除画布。 我最近添加了一个橡皮擦工具,使用globalCompositionProperty(desitnation-out)擦除画布的选定区域。这部分工作良好,但当我去撤销擦除,整个画布被清除,重做功能不起作用。当我用常规的绘图工具(使用source-over)恢

  • 我在发布要绘制到屏幕的擦除背景事件时遇到麻烦。在我的完整代码中,我想在单击按钮时绘制一个位图(dc.drawBitmap())。我通过发布一个由自定义绑定方法捕获的EVT_ERASE_BACKGROUND事件来实现这一点。但是,一旦它在那个方法中,正常工作的event.getDc()方法就会失败。 下面是一个简化的代码,也有相同的结果: null 我该怎么解决这个?