47 votes

Texte anticrénelé sous-pixel sur l'élément canvas de HTML5

J'ai du mal à comprendre la façon dont l'élément de toile anticrénelage du texte et j'espère que vous pourrez m'aider.

Dans la capture d'écran suivante, l'élément supérieur "Quick Brown Fox" est un élément H1 et l'élément inférieur est un élément canvas avec du texte rendu. En bas, vous pouvez voir les deux "F" placés côte à côte et agrandis. Remarquez que l'élément H1 se fond mieux dans l'arrière-plan :

example 'F'

Voici le code que j'utilise pour rendre le texte de la toile :

        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 ?

10 votes

+1 C'est une excellente question ! Le texte laid sur les éléments de la toile est très visible pour les utilisateurs finaux car il se trouve à proximité du "bon" texte qui se trouve ailleurs sur la page.

31voto

SirWart Points 627

Il est maintenant possible d'obtenir un rendu des polices 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é ceci à partir de ce article de blog .

14voto

Matt Mazur Points 265

Je réponds à ma propre question :

C'est possible en utilisant la technique démontrée sur ce site :

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

Le seul problème est qu'il est trop lent à mettre en œuvre dans une application de production. Si quelqu'un trouve une méthode plus rapide, faites-le moi savoir.

0 votes

Le lien semble être cassé. Je crois que c'est ici, cependant (via WayBack Machine) : web.archive.org/web/20120714122710/http://www.bel.fi/~alankila/

7voto

Joubert Nel Points 1559

Matt, j'ai rencontré le même problème la semaine dernière, qui, dans mon cas, s'est avéré être dû à des 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 sur posterous est mort, alors voici l'essentiel avec le code source : https://gist.github.com/joubertnel/870190

Et le snippet 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);

6 votes

Posterous n'existe plus, c'est donc un lien mort.

0 votes

C'est la solution si vous avez résolu le problème de l'anticrénelage et que vous voyez toujours de grosses polices. J'ai résolu l'antialiasing en soustrayant le %1 de la valeur (pixel cassé) puis j'ai aussi fait ceci.

2voto

j5v Points 21

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

Schéma de la méthode

Il dessine sur un canevas, qui est ensuite dessiné à l'écran pour tirer parti des sous-pixels à bandes RVB. Elle fonctionne également avec les canaux alpha. Notez que cela peut ne pas fonctionner si vous utilisez un affichage en mode portrait, des pixels non rayés, ou si votre navigateur affiche les canevas à une résolution inférieure à celle de votre affichage.

Il est possible de l'affiner, mais c'est un gain important pour une méthode simple.

1voto

Phrogz Points 112337

C'est ce qu'on appelle génériquement anticrénelage sous-pixel ou ClearType sur Windows. Je n'ai connaissance d'aucune combinaison de système d'exploitation et de navigateur qui prenne actuellement en charge cette fonction pour Canvas.

Je serais intéressé de voir des tests utilisant des décalages inférieurs à un pixel pour le texte afin de voir si un navigateur utilise des indications basées sur les pixels pour le rendu de la police (alignement des ascendants sur les limites des pixels, par exemple). Je pense que non.

Editar : Mon hypothèse était fausse ; il semblerait que Safari, Chrome et Firefox utilisent tous des indications de police en pixels. Safari et Chrome semblent faire de même, en s'adaptant aux limites des pixels entiers, mais sont différents de Firefox (s'adaptant aux limites des demi-pixels ?). Voir les résultats visuels des tests (sur OS X) ici : http://phrogz.net/tmp/canvas_text_subpixel.html

1 votes

Merci de l'avoir testé. Vous pourriez également aimer ceci : bel.fi/~alankila/lcd

0 votes

@MattMazur Joli ! Vous devriez poster cela comme une réponse afin de pouvoir l'accepter.

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