2016-11-23 2 views
11

縮尺で描かれたパスGLES20RecordingCanvasは、あたかもビットマップでスケーリングされていないかのように描画され、次に拡大縮小されたような品質を持ちます。スケーリングされたGLES20RecordingCanvasとシンプルなキャンバスで描画されるパスが異なる性質を持つ理由を教えてください。

逆に、ビットマップをバッキングしてCanvasを作成し、同じスケーリング変換をCanvasオブジェクトに適用すると、非常に優れたビットマップが得られます。

ここで、両方の円は、Path.addCircleで描画され、Canvas.scaleを使用して描画されます。上の円はスケーリングされたGLES20RecordingCanvasで描画され、下位はスケーリングされた単純なCanvasのバッキングビットマップで描画されます。

いくつかのコード:

public class TestPathRenderer extends View { 

    ... 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 

     int measuredWidth = getMeasuredWidth(); 
     int measuredHeight = getMeasuredHeight(); 
     float distortedWidth = getDistortedWidth(); 
     float distortedHeight = getDistortedHeight(); 

     path.reset(); 
     path.addCircle(distortedWidth/2f, distortedHeight/2f, Math.min(distortedWidth/2f, distortedHeight/2f), Path.Direction.CW); 

     bitmap = assembleNewBitmap(measuredWidth, measuredHeight); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     switch (renderMode) { 
      case RENDER_MODE_WO_BITMAP: 
       drawOnCanvas(canvas); 
       break; 
      case RENDER_MODE_WITH_BITMAP: 
       canvas.drawBitmap(bitmap, 0f, 0f, paint); 
       break; 
      default: 
       throw new UnsupportedOperationException("Undefined render mode: " + renderMode); 
     } 
    } 

    private Bitmap assembleNewBitmap(int w, int h) { 
     Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     Canvas canvas = new Canvas(bitmap); 
     drawOnCanvas(canvas); 
     return bitmap; 
    } 

    private void drawOnCanvas(@NonNull Canvas canvas) { 
     canvas.save(); 
     canvas.scale(DISTORTION_FACTOR, DISTORTION_FACTOR); 
     canvas.drawPath(path, paint); 
     canvas.restore(); 
    } 
} 

Full example

私はこれらの2例と品質の違いを理解することはできません。私にとっては、彼らは交換可能でなければならないようです。

答えて

2

スケーリング時の品質の低下は、Android docsによるハードウェアアクセラレーションの制限です。

1

あなたの質問を見てから、私はGLES20RecordingCanvasクラスのソースコードをチェックすることにしました。そして、私が知ったことは次のとおりです。

GLES20RecordingCanvasGLES20Canvasは、HardwareCanvasから続きます。このHardwareCanvasクラスはCanvasから拡張されています。しかし、私が気づいた主な違いは、isHardwareAcceleratedMethod()が真を返すことを上書きすることです。

私は、GLES20RecordingCanvasは、ハードウェアアクセラレーションでビットマップをレンダリングすることを前提としていますが、キャンバスはそうではありません。これはたぶんGLES20RecorgingCanvasで品質が低下する理由です。

+0

'canvas.isHardwareAccelerated()'の値を 'Canvas'と' GLES20RecordingCanvas'の両方でチェックすることができます –

+1

質問はそれとは逆です。それが逆であれば、OpenGLは頂点を使ってシェイプを表現し、ビットマップはピクセルを使用しているので、完璧な意味があります。 –

+0

@YoniGrossありがとう。私は誤解しました。私の答えを編集しました –

関連する問題