【问题标题】:Subpixel anti-aliased text on HTML5's canvas elementHTML5 的 canvas 元素上的亚像素抗锯齿文本
【发布时间】:2011-05-31 20:35:30
【问题描述】:

我对画布元素抗锯齿文本的方式有点困惑,希望大家能提供帮助。

在下面的截图中,顶部的“Quick Brown Fox”是一个 H1 元素,底部是一个画布元素,上面呈现了文本。在底部,您可以看到两个“F”并排放置并放大。注意 H1 元素如何更好地与背景融合:

这是我用来渲染画布文本的代码:

        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);
        }

是否可以在画布上以一种看起来与 H1 元素相同的方式呈现文本?为什么它们不同?

【问题讨论】:

  • +1 这是个好问题!画布元素上丑陋的文本对最终用户来说非常明显,因为它与页面上其他地方的“好”文本非常接近。

标签: html text canvas antialiasing subpixel


【解决方案1】:

您可以通过相当简单的技术使字体更清晰。

您可以在 CSS 中将画布缩放两倍:

canvas {
    transform-origin: left top;
    transform: scale(0.5);
}

在 HTML 中,画布的尺寸加倍:

<canvas width="(width*2)" height="(height*2)">

最后以双倍大小在画布上绘制所有内容。

你会发现字体清晰了很多。

这与 HTML 中的 H1 并不完全相同,但看起来比正常的字体渲染要好得多。

【讨论】:

    【解决方案2】:

    回答我自己的问题:

    可以使用本网站上演示的技术:

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

    唯一的问题是它太慢了,无法在生产应用中实现。如果有人遇到更快的方式,请告诉我。

    【讨论】:

    【解决方案3】:

    这是一种对任何画布内容(文本、图像、矢量等)进行亚像素渲染的方法。 http://johnvalentine.co.uk/archive.php?art=tft.

    方法概要

    它在画布上绘制,然后将其绘制到屏幕上以利用 RGB 条纹子像素。它也适用于 Alpha 通道。请注意,如果您使用的是纵向显示、非条纹像素,或者如果您的浏览器以比您的显示器更低的分辨率显示画布,这可能不起作用。

    有微调的余地,但对于一个简单的方法来说,这是一个很大的收获。

    【讨论】:

      【解决方案4】:

      Matt,上周我遇到了(相同/相似的)问题,就我而言,这是因为我正在测试的设备上的像素密度存在差异;我今晚写了这篇文章-http://joubert.posterous.com/crisp-html-5-canvas-text-on-mobile-phones-and

      posterous 的链接已经失效,所以这里是源代码的要点: https://gist.github.com/joubertnel/870190

      还有 sn-p 本身:

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

      【讨论】:

      • Posterous 已经不在了,所以这是一个死链接。
      • 如果您解决了抗锯齿并且仍然看到胖字体,这就是解决方案。我通过减去值(破碎像素)的 %1 来解决抗锯齿问题,然后我也这样做了。
      【解决方案5】:

      现在可以通过创建不透明的画布上下文来获得亚像素字体渲染。在 Safari 和 Chrome 中,你可以使用这个 sn-p 来获得它:

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

      我是从这个blog post 找到的。

      【讨论】:

      • 这确实提高了我项目中文本的易读性。谢谢。
      • 任何想法如何让它在 FF 或 IE(最新版本)中工作?
      • @sunnymoon:Adobe 博客文章说这是一种对画布文本进行亚像素抗锯齿的方法。它适用于 Chrome,但不适用于 FF 或 IE。测试自己:codepen.io/timo22345/pen/avvOmp。下面的文本框应该具有亚像素抗锯齿功能。
      • @Timo,我在 FF 40.0.3 上,我看到 LCD 子像素抗锯齿在两个画布中都有彩色边缘(又名 ClearType)。那么,它在 FF 中确实有效,对吧?
      • @sunnymoon:什么操作系统?我在 OSX 中测试过。
      【解决方案6】:

      这在 Windows 上通常称为 subpixel anti-aliasingClearType。我不知道目前支持 Canvas 的任何操作系统/浏览器组合。

      我很想看看一些使用文本子像素偏移量的测试,看看是否有任何浏览器甚至使用基于像素的字体渲染提示(例如,在像素边界上对齐升序)。我的假设是否定的。

      编辑:我的假设是错误的;看起来 Safari、Chrome 和 Firefox 都使用了一些像素字体提示。 Safari 和 Chrome 看起来一样,都对齐到整个像素边界,但与 Firefox 不同(对齐到半像素边界?)。在此处查看测试的视觉结果(在 OS X 上):http://phrogz.net/tmp/canvas_text_subpixel.html

      【讨论】:

      • 感谢您的测试。你可能也喜欢这个:bel.fi/~alankila/lcd
      • @MattMazur 不错!您应该将其发布为答案,以便您接受它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-23
      • 1970-01-01
      • 1970-01-01
      • 2011-10-15
      • 2012-12-03
      • 2012-08-23
      相关资源
      最近更新 更多