web-dev-qa-db-fra.com

Sous-pixel anti-aliasé sur l'élément canvas de HTML5

Je suis un peu confus avec la façon dont le texte de l'anti-alias de l'élément canvas et j'espère que vous pouvez tous aider.

Dans la capture d'écran suivante, le "Quick Brown Fox" du haut est un élément H1 et celui du bas est un élément canvas avec du texte rendu dessus. En bas, vous pouvez voir les deux "F" placés côte à côte et zoomés. Remarquez comment l'élément H1 se mélange mieux avec l'arrière-plan:

Voici le code que j'utilise pour rendre le texte du canevas:

        var canvas = document.getElementById('canvas');
        if (canvas.getContext){

            var ctx = canvas.getContext('2d');
            ctx.fillStyle = 'black';
            ctx.font = '26px Arial';
            ctx.fillText('Quick Brown Fox', 0, 26);
        }

Est-il possible de rendre le texte sur le canevas de manière à ce qu'il soit identique à l'élément H1? Et pourquoi sont-ils différents?

45
Matt Mazur

Répondre à ma propre question:

Il est possible d'utiliser la technique démontrée sur ce site:

https://bel.fi/alankila/lcd/

Le seul problème est que sa mise en œuvre est trop lente dans une application de production. Si quelqu'un traverse un moyen plus rapide, faites-le moi savoir.

14
Matt Mazur

Il est maintenant possible d'obtenir un rendu de police sous-pixel en créant un contexte de toile opaque. Dans Safari et Chrome vous pouvez l'obtenir en utilisant cet extrait:

var ctx = canvas.getContext("2d", {alpha: false})

J'ai trouvé cela dans ce article de blog .

23
sirwart

Matt, je me suis assis avec le problème (identique/similaire) la semaine dernière, qui, dans mon cas, s'est avéré être dû aux différences de densité de pixels sur les appareils que je testais; J'ai écrit à ce sujet ce soir - http://joubert.posterous.com/crisp-html-5-canvas-text-on-mobile-phones-and

Le lien à posterous est mort, voici donc le Gist avec le code source: https://Gist.github.com/joubertnel/87019

Et l'extrait lui-même:

  // Output to Canvas without consideration of device pixel ratio
  var naiveContext = $('#naive')[0].getContext('2d');    
  naiveContext.font = '16px Palatino';
  naiveContext.fillText('Rothko is classified as an abstract expressionist.', 10, 20);

  // Output to Canvas, taking into account devices such as iPhone 4 with Retina Display
  var hidefCanvas = $('#hidef')[0];
  var hidefContext = hidefCanvas.getContext('2d');

  if (window.devicePixelRatio) {
    var hidefCanvasWidth = $(hidefCanvas).attr('width');
    var hidefCanvasHeight = $(hidefCanvas).attr('height');
    var hidefCanvasCssWidth = hidefCanvasWidth;
    var hidefCanvasCssHeight = hidefCanvasHeight;

    $(hidefCanvas).attr('width', hidefCanvasWidth * window.devicePixelRatio);
    $(hidefCanvas).attr('height', hidefCanvasHeight * window.devicePixelRatio);
    $(hidefCanvas).css('width', hidefCanvasCssWidth);
    $(hidefCanvas).css('height', hidefCanvasCssHeight);
    hidefContext.scale(window.devicePixelRatio, window.devicePixelRatio);               
  }

  hidefContext.font = "16px Palantino";
  hidefContext.fillText("Rothko is classified as an abstract expressionist.", 10, 20);
7
Joubert Nel

Voici une façon de faire un rendu sous-pixel pour tout contenu de canevas (texte, images, vecteurs, etc.). http://johnvalentine.co.uk/archive.php?art=tft .

Aperçu de la méthode

Il dessine sur une toile, qui est ensuite attirée sur l'écran pour tirer parti des sous-pixels à rayures RVB. Cela fonctionne aussi avec les canaux alpha. Notez que cela peut ne pas fonctionner si vous utilisez un affichage portrait, des pixels non rayés ou si votre navigateur affiche des toiles à une résolution inférieure à votre affichage.

Il y a place pour un réglage fin, mais c'est un gros gain pour une méthode simple.

2
j5v

Ceci est génériquement appelé anti-aliasing sous-pixel , ou ClearType sous Windows. Je ne connais aucune combinaison OS/navigateur qui prend actuellement en charge ceci pour Canvas.

Je serais intéressé de voir certains tests utilisant des décalages de sous-pixels pour le texte pour voir si des navigateurs utilisent même une indication basée sur les pixels du rendu de la police (alignement des ascendeurs sur les limites des pixels, par exemple). Mon hypothèse serait non.

Edit : Mon hypothèse était fausse; il semblerait que Safari, Chrome et Firefox utilisent tous une indication de police de pixels. Safari et Chrome semblent identiques, s'alignant sur des limites de pixels entières, mais sont différents de Firefox (s'alignant sur des frontières d'un demi-pixel?). Voir les résultats visuels des tests (sur OS X) ici: http://phrogz.net/tmp/canvas_text_subpixel.html

1
Phrogz