Создание приложения для рисования пером/ластиком с фоном. Ластик стирает фоновое изображение, он должен стирать только ручку

Я следовал коду отпечатка пальцев и другому коду, чтобы создать приложение, которое позволяет вам рисовать на экране с фоновым изображением, которое можно рисовать поверх. Кроме того, я хотел бы сделать ластик, который стирает только перо, а не фоновое изображение. Я думаю, что для этого мне нужно использовать два холста, но я не мог понять, как это будет работать с 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>

person Andy    schedule 02.04.2014    source источник
comment
и вы хотите, чтобы мы написали для него код?   -  person Emmanuel    schedule 03.04.2014
comment
Я отредактировал свой вопрос. Если бы вы могли дать мне подсказки о том, что делать, я был бы очень признателен.   -  person Andy    schedule 03.04.2014


Ответы (1)


Я понял. В итоге я поместил фоновое изображение в качестве фона, который можно рисовать на контейнере, а не рисовать его на холсте.

В onDraw я закомментировал эту строку:

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

В onCreate я добавил:

BitmapDrawable ob = new BitmapDrawable(backgroundBitmap);
container.setBackgroundDrawable(ob);
person Andy    schedule 03.04.2014