12

Path drawn on scaled GLES20RecordingCanvas has quality as if it was drawn unscaled in bitmap and then up-scaled.

In contrast, if I create Canvas with backing bitmap and then apply the same scaling transformations to Canvas object I get much superior bitmap.

Here both circles are drawn with Path.addCircle and using Canvas.scale. Upper circle is drawn with scaled GLES20RecordingCanvas and lower is drawn with scaled simple Canvas with backing bitmap.

Some code:

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

I can't understand the quality difference with these two cases. For me it seems that they have to be interchangeable.

4

2 回答 2

3

根据Android 文档,缩放期间质量差是硬件加速的限制。

于 2017-02-08T15:00:42.180 回答
1

看到您的问题后,我决定查看该GLES20RecordingCanvas课程的源代码。这就是我发现的:

GLES20RecordingCanvas延伸自GLES20Canvas延伸自HardwareCanvas。这个HardwareCanvas类从Canvas. 但我注意到的主要区别是它覆盖了isHardwareAcceleratedMethod()返回的 true。

所以我的假设是GLES20RecordingCanvas使用硬件加速渲染位图,而 Canvas 没有。这可能就是您使用GLES20RecorgingCanvas.

于 2017-02-08T12:42:41.217 回答