2017-02-20 12 views
0

私は開発中のアプリに半透明の消しゴムブラシを書こうとしていますが、実装方法によって2つの問題が発生することがわかりました。うまくいけば、私が指摘できる回避策があります。キャンバスに半透明の消しゴムブラシ

コードサンプルはモノラルでドロイドある/ 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; 
    } 

したがって、描画中に消しゴム線を描画する方法は2通りあります。最初は描画キャンバス(canvasBitmapに書き込む)に描画し、2番目の描画はcanvasOnDraw)で描画します。

私の問題は、次のとおりです。

私は私が消去ラインが徐々に、より多くの透明取得スタッキング効果を得るDrawCanvasに上描きした場合。各OnDrawループの間、消しゴムパスがcanvasBitmapに焼き付けられているので、これは理解できるものです。

OnDrawによって提供されるcanvasに直接描画すると、「black line」の問題が発生しますが、これも何も消去されないので意味があります。パスがUpイベントのcanvasBitmapに描画されると、すべてが正しいように見えて、素晴らしい半透明の消しゴム線があります。

私は「black line」の問題は認識していませんが、何も見つかりませんでした。また、canvasBitmapをキャッシュする方法を考えてみましたが、ドローイベントが進行中にアクティブなコピーをMoveイベントで描画するのではなく使用しています。

解決策を提案する可能性のある人はいますか? Javaは、C#に移植するのが簡単なので大丈夫です。

事前に感謝します。 ナイジェル

答えて

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イベントでは、リサイクルしてから変数をnullにします。

しかし、それは動作しません。

これ以上の素晴らしいアイデアはありません。

関連する問題