我正在关注API演示中的“FingerPaint”演示。
我需要获得“喷枪”效果,因为当我在同一个地方画画时,它会变得更暗更暗。
请看图片:
因为你可以看到中心比较暗,因为我在同一个地方涂了多次油漆。
请问如何获得相同的效果,如果画了一次以上会变暗一点?
编辑编辑编辑
建议的
mPaint.setAlpha(0x80)
有点工作,但只有当我松开触摸然后再次触摸时,如果我不释放并将手指放在屏幕上,则不会达到效果。
关键在于,如果不将手指从屏幕上松开,则无法达到效果,如果继续绘图而不释放触摸,则在涂漆时不会变暗。如果您松开触摸然后再次绘制,则会获得效果
这是我得到的结果。我不想要:
这将是理想的结果:
这是从API演示中获取的代码:
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;
}
}
}
答案 0 :(得分: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;
}
}
}
快照
答案 1 :(得分: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)。使用白色背景和黑色涂料进行结果测试。
答案 2 :(得分: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。但是当你绘制曲折时,你可以看到它看起来不太好