我正在尝试将半透明橡皮刷写入我正在开发的应用程序中,但发现了两个问题,具体取决于它是如何实现的。希望有一个我可以指出的解决方法。
代码样本是单声道droid / xamarin
所以,通常我有一个设置,它将路径绘制到绘图画布上。我的视图的OnDraw
方法绘制了它的基本位图,然后是我的路径。
// Canvas is set up elsewhere
canvasBitmap = Bitmap.CreateBitmap(w, h, Bitmap.Config.Argb8888);
DrawCanvas.SetBitmap(canvasBitmap);
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
// Draw the saved canvas bitmap
canvas.DrawBitmap(canvasBitmap, 0, 0, canvasPaint);
// On top of that draw the current path
canvas.DrawPath(DrawPath, DrawPaint);
}
public bool OnTouch(View view, MotionEvent ev)
{
float touchX = ev.GetX();
float touchY = ev.GetY();
switch (ev.Action)
{
case MotionEventActions.Down:
if (Editable)
{
// I've removed a bunch of code here but it basically
// moves the path start to the touch point and sets
// up the brush to start erasing. It does set the
// porterduff mode to dstOur
DrawPaint.SetMaskFilter(null);
DrawPaint.SetXfermode( new PorterDuffXfermode(PorterDuff.Mode.DstOut));
DrawPath.MoveTo(touchX, touchY);
} else { return false; }
break;
case MotionEventActions.Move:
// Just draws a line to the new touch coordinates
DrawPath.LineTo(touchX, touchY);
break;
case MotionEventActions.Up:
case MotionEventActions.Cancel:
// saves some data about the path and draws to the drawing canvas.
DrawCanvas.DrawPath(DrawPath, DrawPaint);
// Recycle it
DrawPath.Reset();
break;
}
return true;
}
因此在绘制橡皮擦线时有两种方法可以绘制橡皮擦线。第一种是绘制绘图画布(写入canvasBitmap
),第二种是直接绘制canvas
提供的OnDraw
。
我的问题如下:
如果我画到DrawCanvas
,我会得到一个堆叠效果,其中擦除的线逐渐变得越来越透明。这是可以理解的,因为在每个OnDraw
循环中,橡皮擦路径被烘焙到canvasBitmap
。
如果我直接绘制到canvas
提供的OnDraw
,我会遇到“black line”问题,这也是有意义的,因为它正在删除。当路径被绘制到canvasBitmap
事件中的Up
时,一切看起来都正确,并且有一条漂亮的半透明橡皮擦线。
理想情况下,有一个不同的解决方案,我不知道“black line”问题,但我找不到任何东西。我也尝试过考虑缓存canvasBitmap
的方法,并且在绘制事件正在进行时使用而不是Move
事件所吸引的主动副本。
有没有人有什么我可以看看哪些可能暗示解决方案? Java很好,因为它很容易移植到c#。
非常感谢提前! 佰
答案 0 :(得分:0)
如果没有比我更有经验/聪明才智的人,我会以一种可怕的方式绕过它。当我继续寻找一种更聪明的方法时,它可能对其他人有帮助。
当Down
事件发生时,我将位图的干净副本抓取到临时变量中。在每个OnDraw
事件中,我读取了清理位图,然后在其上绘制擦除路径。
可怕的是,每个OnDraw
事件都有一个位图复制方法,以确保不会发生擦除路径加倍。
OnDraw( Canvas canvas )
{
tempBitmap.Recycle();
tempBitmap = _drawingBitmap.Copy(_drawingBitmap.GetConfig(), true);
DrawCanvas.DrawColor(Color.Transparent, PorterDuff.Mode.Clear);
DrawCanvas.DrawBitmap(tempBitmap, 0, 0, DrawPaint));
DrawCanvas.DrawPath(DrawPath, DrawPaint);
}
位图回收显然非常关键。在触摸侦听器中的.Up
事件中,它再次循环,然后使变量为空。
不漂亮,但确实有效。
任何更好的想法都非常赞赏!