Subpixel anti-aliased text on HTML5's canvas element

北城余情 提交于 2019-11-27 11:39:31

It's now possible to get sub-pixel font rendering by creating an opaque canvas context. In Safari and Chrome you can get this using this snippet:

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

I found this from this blog post.

Matt Mazur

Answering my own question:

It is possible using the technique demonstrated on this site:

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

The only problem is that its too slow to implement in a production app. If anyone runs across a faster way please let me know.

Joubert Nel

Matt, I sat with the (same/similar) problem last week, which, in my case, turned out to be because of differences in pixel densities on the devices I was testing; I wrote about it tonight - http://joubert.posterous.com/crisp-html-5-canvas-text-on-mobile-phones-and

The link at posterous is dead, so here is the gist with the source code: https://gist.github.com/joubertnel/870190

And the snippet itself:

  // 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); 
j5v

Here's a way of doing sub-pixel rendering for any canvas content (text, images, vectors, etc). http://johnvalentine.co.uk/archive.php?art=tft.

Outline of the method

It draws onto a canvas, which is then drawn to the screen to take advantage of RGB-striped subpixels. It works with alpha channels too. Note that this might not work if you are using a portrait display, non-striped pixels, or if your browser displays canvases at a lower resolution than your display.

There's scope for fine-tuning, but it's a big gain for a simple method.

This is generically called subpixel anti-aliasing, or ClearType on Windows. I'm not aware of any OS/browser combinations that currently support this for Canvas.

I'd be interested to see some tests using sub-pixel offsets for the text to see if any browsers even use pixel-based hinting of the font rendering (aligning ascenders on pixel boundaries, for example). My assumption would be no.

Edit: My assumption was wrong; it would appear that Safari, Chrome, and Firefox all utilize some pixel font hinting. Safari and Chrome appear the same, snapping to whole pixel boundaries, but are different from Firefox (snapping to half-pixel boundaries?). See the visual results of testing (on OS X) here: http://phrogz.net/tmp/canvas_text_subpixel.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!