12

我正在关注 API Demos 中的“FingerPaint”演示。

我需要获得“喷枪”效果,因为当我在同一个地方画画时,它会变得越来越暗。

请看图片:

正如你所看到的,中心更暗,因为我在同一个地方多次通过油漆。

请问我如何获得相同的效果,如果超过一次绘制会使斑点变暗?

在此处输入图像描述

编辑 编辑 编辑

建议的

mPaint.setAlpha(0x80) 

一种工作,但只有当我释放触摸然后再次触摸时,如果我不释放并保持手指在屏幕上,则无法达到效果。

关键是,如果您不从屏幕上松开手指,您就不会达到效果,如果您在不松开触摸的情况下继续绘画,则绘画结束时它不会变暗。如果您释放触摸然后再次绘制,您将获得效果

这是我得到的结果。我不想:

在此处输入图像描述

这将是期望的结果:

在此处输入图像描述


这是取自 API Demos 的代码:

public class FingerPaint extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0x44FF0000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

}

private Paint mPaint;

public class MyView extends View {

    private static final float MINP = 0.25f;
    private static final float MAXP = 0.75f;

    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;

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

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(0xFFAAAAAA);

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

        canvas.drawPath(mPath, mPaint);
    }

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

    private void touch_start(float x, float y) {
        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);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        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;
    }
}

}
4

3 回答 3

5

我只对你的代码做了一些小的改动。

 mPaint.setColor(Color.BLACK);// changed color to balck
 mPaint.setAlpha(0x80); // only change    

活动课

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new MyView(this));

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setAlpha(0x80); // only change
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

}

private Paint mPaint;

public class MyView extends View {

    private static final float MINP = 0.25f;
    private static final float MAXP = 0.75f;

    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;

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

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(0xFFAAAAAA);

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

        canvas.drawPath(mPath, mPaint);
    }

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

    private void touch_start(float x, float y) {
        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);
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        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;
    }
}

}

快照

在此处输入图像描述

于 2013-06-12T09:27:59.397 回答
4

这种方法更像是 Photoshop 之类的模拟方式:沿路径集成并绘制单独的油漆飞溅,其间的间距可调节。

在此处输入图像描述

public class DrawView extends View {
public Paint mPaint;

private Bitmap mBitmap;
private Canvas mCanvas;

private int strokeRadius;
private ShapeDrawable mBrush;
private Paint mBitmapPaint;

private float mPreviousX, mPreviousY;

public DrawView(Context context, AttributeSet attrs) {
    super( context,  attrs);

    mBitmapPaint = new Paint(Paint.DITHER_FLAG);

    int strokeWidth = 20;

    strokeRadius = strokeWidth/2;

    Shape brushShape = new OvalShape();

    mBrush = new ShapeDrawable(brushShape);

    Paint paint = mBrush.getPaint();

    // radial gradient shader with a transparency falloff, if you don't want this,
    // just set a color on the paint and remove the setShader call
    Shader shader = new RadialGradient(strokeRadius, strokeRadius, strokeRadius,
            Color.argb(255, 0, 0, 0), Color.argb(0, 0, 0, 0), Shader.TileMode.CLAMP);

    paint.setShader(shader);
    paint.setAlpha(0x10);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(0xFF00B8F5);

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

private void touch_start(float x, float y) {
    mPreviousX = x;
    mPreviousY = y;
}

private void touch_move(MotionEvent event)
{
    float x = event.getX();
    float y = event.getY();

    // get vector from previous to current position
    float xdist = x - mPreviousX;
    float ydist = y - mPreviousY;

    // get the length
    float segmentLength = (float) Math.sqrt(xdist * xdist + ydist * ydist);

    // derive a suitable step size from stroke width
    float stepSize = Math.max(strokeRadius / 10, 1f);

    // calculate the number of steps we need to take
    // NOTE: this draws a bunch of evenly spaced splashes from the start point
    // to JUST BEFORE the end point. The end point will be drawn by the start point of the
    // next stroke, or by the touch_up method. If we drew both the start and
    // end point there it would be doubled up
    int steps = Math.max(Math.round(segmentLength / stepSize), 2);

    for(int i = 0; i < steps; ++i)
    {
        int currentX = (int) (mPreviousX + xdist * i / steps);
        int currentY = (int) (mPreviousY + ydist * i / steps);

        drawSplash(currentX, currentY);
    }

    // update the previous position
    mPreviousX = x;
    mPreviousY = y;
}

private void touch_up(MotionEvent event) {
    drawSplash((int) event.getX(), (int)event.getY());
}

/**
 * draws the brush to the canvas, centered around x and y
 * @param x
 * @param y
 */
private void drawSplash(int x, int y)
{
    mBrush.setBounds(x - strokeRadius, y - strokeRadius, x + strokeRadius, y + strokeRadius);

    mBrush.draw(mCanvas);

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    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(event);
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up(event);
        invalidate();
        break;
    }
    return true;
}
}

编辑:快照(Raghunandan)。使用白色背景和黑色油漆进行结果测试。

在此处输入图像描述

于 2013-06-16T13:46:46.643 回答
2

找到了解决方案。对于那些可能感兴趣的人:

public class DrawView extends View {
public Paint mPaint;
private Paint mPaint1;
private Paint mPaint2;

private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;

public DrawView(Context context, AttributeSet attrs) {
    super( context,  attrs);

    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mPaint = new Paint();
    mPaint.setAlpha(0x80);
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(0x44000000);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.BUTT);
    mPaint.setStrokeWidth(5);

}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mCanvas = new Canvas(mBitmap);

}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(0xFF00B8F5);

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

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

private void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
    //mCanvas.drawPoint(x, y, mPaint);

}

private void touch_move(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    Path npath=new Path();
    npath.moveTo(mX, mY);
    npath.lineTo( x ,y );
    mX=x;
    mY=y;
    mCanvas.drawPath(npath, mPaint);
    npath.reset();
    //Log.e("","sto disegando");
}

private void touch_up() {

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    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(event);
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        break;
    }
    return true;
}
}

编辑:附加我的模拟器(Raghunandan)的快照。我使用您的代码没有任何变化,只是增加了笔画宽度,如下所示。

慢慢画的时候不好看。

在此处输入图像描述

屏幕截图笔画宽度 12 如果你画一条直线没问题。但是当你画 zig zag 时,你会发现它看起来不太好

在此处输入图像描述

于 2013-06-15T22:05:10.723 回答