47

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

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

示例“F”

这是我用来呈现画布文本的代码:

        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 元素相同?为什么它们不同?

4

6 回答 6

30

现在可以通过创建不透明的画布上下文来获得亚像素字体渲染。在 Safari 和 Chrome 中,您可以使用以下代码段获取此信息:

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

我从这篇博文中找到了这个。

于 2015-01-27T00:50:33.637 回答
14

回答我自己的问题:

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

https://bel.fi/alangila/lcd/

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

于 2010-12-29T15:45:36.330 回答
7

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

后面的链接已经死了,所以这里是源代码的要点: https ://gist.github.com/joubertnel/870190

和片段本身:

  // 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);
于 2011-03-15T02:38:21.997 回答
2

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

方法概要

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

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

于 2013-07-17T23:18:56.237 回答
1

这通常称为子像素抗锯齿,或Windows 上的ClearType。我不知道目前支持 Canvas 的任何操作系统/浏览器组合。

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

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

于 2010-12-29T02:17:34.017 回答
0

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

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

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

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

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

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

您会注意到字体更加清晰。

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

于 2021-11-17T13:53:54.587 回答