11 votes

Pourquoi les chemins dessinés sur le GLES20RecordingCanvas mis à l'échelle et sur le Canvas simple ont-ils des qualités différentes ?

Chemin dessiné à l'échelle GLES20RecordingCanvas a la même qualité que s'il avait été dessiné sans échelle en bitmap, puis mis à l'échelle.

En revanche, si je crée Canvas avec le bitmap d'arrière-plan et ensuite appliquer les mêmes transformations d'échelle à Canvas objet j'obtiens un bitmap bien supérieur.

Ici, les deux cercles sont dessinés avec Path.addCircle et en utilisant Canvas.scale . Le cercle supérieur est dessiné avec l'échelle GLES20RecordingCanvas et inférieur est dessiné avec une échelle simple Canvas avec bitmap d'appui.

Un certain 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();
    }
}

Exemple complet

Je n'arrive pas à comprendre la différence de qualité entre ces deux cas. Pour moi, il semble qu'ils doivent être interchangeables.

2voto

Vang Points 843

La mauvaise qualité lors de la mise à l'échelle est une limitation de l'accélération matérielle selon Docs Android .

1voto

Après avoir vu votre question, j'ai décidé de consulter le code source de l'application GLES20RecordingCanvas classe. Et voilà ce que j'ai découvert :

GLES20RecordingCanvas s'étend de GLES20Canvas qui s'étend de HardwareCanvas . Ce site HardwareCanvas s'étend de Canvas . Mais la principale différence que j'ai remarquée est qu'elle remplace la fonction isHardwareAcceleratedMethod() renvoyant à la vérité.

Donc mon hypothèse est que le GLES20RecordingCanvas rend le bitmap avec l'accélération matérielle alors que Canvas ne le fait pas. Et c'est probablement la raison pour laquelle vous obtenez une qualité moindre avec l'option GLES20RecorgingCanvas .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X