0

我想创建一个画笔效果,当用户在屏幕上拖动他/她的手指时,画笔只会改变下面图像/位图的 alpha。例如,如果画笔不透明度设置为 50%,那么应用画笔应该

  1. 设置该区域的 alpha/opacity,仅设置该区域而不是整个位图。
  2. 保持位图区域的基础颜色不变。

也就是说,画笔应该只影响 alpha 透明度而不影响颜色。我从以下代码开始:

public class DrawingView extends View {

    //drawing path
    private Path drawPath;
    //drawing and canvas paint
    private Paint drawPaint, canvasPaint;
    //initial color
    private int paintColor = 0xFFFF0000, paintAlpha = 255;
    //canvas
    private Canvas drawCanvas;
    //canvas bitmap
    private Bitmap canvasBitmap;

    //constructor
    public DrawingView(Context context, AttributeSet attrs){
        super(context, attrs);
        setupDrawing();
    }

    //prepare drawing
    private void setupDrawing(){
        drawPath = new Path();
        drawPaint = new Paint();
        drawPaint.setColor(paintColor);
        drawPaint.setAntiAlias(true);
        drawPaint.setStrokeWidth(50);
        drawPaint.setStyle(Paint.Style.STROKE);
        drawPaint.setStrokeJoin(Paint.Join.ROUND);
        drawPaint.setStrokeCap(Paint.Cap.ROUND);
        canvasPaint = new Paint(Paint.DITHER_FLAG);
    }

    //view assigned size
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        drawCanvas = new Canvas(canvasBitmap);
    }

    //draw view
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
        canvas.drawPath(drawPath, drawPaint);
    }

    //respond to touch interaction
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float touchX = event.getX();
        float touchY = event.getY();
        //respond to down, move and up events
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            drawPath.moveTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_MOVE:
            drawPath.lineTo(touchX, touchY);
            break;
        case MotionEvent.ACTION_UP:
            drawPath.lineTo(touchX, touchY);
            drawCanvas.drawPath(drawPath, drawPaint);
            drawPath.reset();
            break;
        default:
            return false;
        }
        //redraw
        invalidate();
        return true;
    }

    //return current alpha
    public int getPaintAlpha(){
        return Math.round((float)paintAlpha/255*100);
    }

    //set alpha
    public void setPaintAlpha(int newAlpha){
        paintAlpha=Math.round((float)newAlpha/100*255);
        drawPaint.setColor(paintColor);
        drawPaint.setAlpha(paintAlpha);
    }
}

正如你所注意到的,这个画笔需要有一个填充颜色。这就是想要避免的。我需要一个透明的刷子,但不是颜色。

如果有其他方法可以实现目标,那很好。

4

1 回答 1

0

设置绝对 alpha 值可能会涉及位图中的一些像素旋转。

你想要的最接近的 Porter-Duff 模式是 DST_OUT,它就像橡皮擦一样。

试试这个代码,看看它是否接近:

       drawPaint.setColor(Color.BLACK);  // the color doesn't really matter
       drawPaint.setAlpha(255 - alpha);  // inverse of the alpha result you want
       drawPaint.setXferMode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

这样做的目的是让每次在同一点上绘制时图像像素越来越亮,这可能不是您想要的。在这种情况下,您将不得不变得更复杂,并将颜色+alpha 路径绘制到单独的位图上,然后使用PorterDuff.Mode.DST_OUT.

不幸的是,您不能简单地实现一个ColorFilter完全符合您要求的自定义。所有这些图形操作都发生在原生空间中,谷歌不希望我们只是凡人搞砸这些东西。

于 2016-11-18T16:09:44.697 回答