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



我遵循了手指绘制代码和其他一些代码创建了一个应用程序,该应用程序允许您在屏幕上绘图,并在顶部绘制背景图像。 此外,我想制作一个橡皮擦工具,只擦除笔,而不是背景图像。 我想我必须为此使用两个画布,但无法弄清楚它如何与 Canvas 的 onDraw 一起工作。

这是我的代码。 现在钢笔画可以工作,橡皮擦画会擦除,但它会擦除背景图像。 我只想让它擦掉笔。

如果你能给我一些提示,我将不胜感激。

===

//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>

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

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

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

在onCreate中,我添加了:

BitmapDrawable ob = new BitmapDrawable(backgroundBitmap);
container.setBackgroundDrawable(ob);

最新更新