1

おはようございます、

私のアプリの一部には、手書きのメモを書き留める機能があります。フィンガーペイントの例の一部を使用して、アプリに「消しゴム」を実装しています。

mPaint.setXfermode(new PorterDuffXfermode(
        PorterDuff.Mode.CLEAR));
mPaint.setStrokeWidth(45);
mPaint.setStrokeCap(Paint.Cap.ROUND);

問題は、私が消去するたびに、ユーザーが消去した黒いパスがあることです。ユーザーが指を離すと消えますが、消去している間はそこにあります。私の友人は、PorterDuffモードはリアルタイムで使用されることは想定されていないと言っていますが、私は彼を信じていません。何か馬鹿げたことをした場合に備えて、コードをもう少し示します。

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(false);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.BUTT);
mPaint.setStrokeWidth(6);
mBitmap = Bitmap.createBitmap(800, 480,Bitmap.Config.ARGB_8888);
bBitmap = Bitmap.createBitmap(800, 480,Bitmap.Config.ARGB_8888);
bBitmap.eraseColor(Color.WHITE);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mBitmapPaint = new Paint();
maxX = maxY = 100;
minX = 750;
minY = 400;

//

private void touch_up() {
    mPath.lineTo(mX, mY);
    mCanvas.drawPath(mPath, mPaint);
    mPath.reset();
}

//

protected void onDraw(Canvas canvas) {    
    canvas.drawBitmap(bBitmap, 0, 0, null);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mPaint);
}

この消しゴムでやりたいことをすることはできますか?これを行うためのより良い方法はありますか?私の友達は実際に正しいですか?

また、消去として白を塗ってみましたが、下にユーザーがマークアップしている画像がある場合があるため、うまくいきません。すべての白いピクセルを通過させて透明にすることはできますが、それは非常に非効率的なようです。

4

5 に答える 5

4

私はこれを適切に行う方法を見つけました。それは黒いストロークなしであなたの指で消去を行います。これが私の解決策です:

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        if(isEraseMode()){
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        }
        touch_start(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_MOVE:
        touch_move(x, y);
        if(isEraseMode()){
            mPath.lineTo(mX, mY);
            mCanvas.drawPath(mPath, mPaint);
            mPath.reset();
            mPath.moveTo(x, y);            
                }
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        break;
    }
    return true;
}  
于 2013-10-25T23:36:03.500 に答える
2

同じ質問があります。

最後に、私は解決策を見つけました。から渡されたキャンバスを使用せず、代わりにコンストラクターで作成されたものをonDraw()使用してください。mCanvas

于 2013-01-12T17:44:12.783 に答える
2

さて、私は解決策を見つけました。同様の問題が発生した場合は、これをここに残しておきます。

case MotionEvent.ACTION_DOWN:
mPaint.setStrokeWidth(25);
            mPaint.setXfermode(new PorterDuffXfermode(
                    PorterDuff.Mode.CLEAR));
            mCanvas.drawCircle(x, y, 10, mPaint);
            isErase = true;
            invalidate();
        }
        touch_start(x, y);
        invalidate();
        break;
case MotionEvent.ACTION_MOVE:   
        if(isErase)
        {
            mCanvas.drawCircle(x, y, 20, mPaint);
        }
        else{
            touch_move(x, y);
        }invalidate();
        break;
于 2012-11-27T20:55:39.567 に答える
1

(回避策)それはあなたに不透明度を犠牲にします。キャンバスを初期化した後、おそらくonCreateあなたの活動の中で。 myCanvasView.setAlpha(0.99f);

于 2017-01-30T17:15:27.353 に答える
0

@Roversに同意します。次のように変更してくださいcanvas

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
    if (!erase) {
        canvas.drawPath(drawPath, drawPaint);
    } else {
        drawCanvas.drawPath(drawPath, drawPaint);
    }
}

メソッドには2種類のキャンバスがありますonDraw->drawCanvascanvas

于 2015-11-17T03:54:38.583 に答える