我想知道是否有可能在Chrome(和/或Safari)的HTML5画布中启用亚像素渲染。
Chrome对HTML进行亚像素渲染,而Firefox则对HTML和Canvas都进行渲染。下面是特定问题的截图:
我想知道是否有可能在Chrome(和/或Safari)的HTML5画布中启用亚像素渲染。
Chrome对HTML进行亚像素渲染,而Firefox则对HTML和Canvas都进行渲染。下面是特定问题的截图:
简短回答:不可能。
这是许多Canvas用户感到沮丧的两个话题之一。
任何类型的子像素渲染/抗锯齿都取决于浏览器。这意味着不同的浏览器很容易以不同的方式呈现事物。
许多人要求抗锯齿成为可以在特定上下文中打开或关闭的选项。目前还没有这样的运气。
尤其需要注意Chrome,因为他们处理子像素渲染的方式在过去的4个月里发生了巨大变化。如果您开始使用Chrome开发者频道,您将预览到他们一直在尝试的东西。他们在这个领域做了很多测试,甚至推出了一些我抱怨过的激进倒退变化。
这里的要点是:
目前我不认为这是可能的。
这是一个难题,因为画布提供了如此多底层控制权给用户。如果画布开始做这样一些智能的事情,它可能会破坏用户预期的一些其他功能。
考虑其他图形元素的亚像素渲染 - 根据应用程序,程序员可能不希望这样做,并且你肯定不希望将亚像素渲染作为全局元素开关任意启用。试想获取特定像素的颜色 - 这里的正确答案是什么?画布是否应该说谎并返回预期的颜色,还是返回实际的颜色(这样我们就必须回答整天的问题:“为什么我制作的黑色像素被测量为暗红色?”)。
有人会认为Firefox在这里做错了。
这里有一种对于任何画布内容(文本、图像、矢量等)进行亚像素渲染的方法。http://johnvalentine.co.uk/subpixel-html5-canvas.htm。
方法概述
它绘制到画布上,然后绘制到屏幕上以利用RGB条纹亚像素。它也适用于alpha通道。请注意,如果您使用的是纵向显示器、非条纹像素或者您的浏览器将画布显示在低于您的显示器分辨率的情况下,则可能无法正常工作。
虽然还有优化的空间,但这是一种简单方法的重大收益。我已经测试过所有浏览器都可以使用,但只适用于画布到屏幕像素比为1:1的情况(但我相信已经提供了解决方案)。
这取决于平台,但是有可能实现。以下是具体步骤:
canvas.getContext('2d', {alpha: false})
-webkit-font-smoothing
属性设置为所需值:auto
、antialias
(模糊)、subpixel-antialias
(带彩色边缘的“LCD”文本)或 none
。这将应用于画布中的所有文本。
以下是在 Mac 上 Chrome 81 中的屏幕截图;绿色矩形中的文本是画布的 fillText
:
这是该文件的源代码:
<!DOCTYPE html>
<style>
canvas {
border: 1px solid green;
}
div {
position: float;
float: left;
}
#a {
-webkit-font-smoothing: auto;
}
#b {
-webkit-font-smoothing: antialiased;
}
#c {
-webkit-font-smoothing: subpixel-antialiased;
}
#d {
-webkit-font-smoothing: none;
}
</style>
<div id="a">
(auto)<br>
??????????<br>
||||||||||<br>
IIIIIIIIII<br>
llllllllll<br>
//////////<br>
</div>
<div id="b">
(antialiased)<br>
??????????<br>
||||||||||<br>
IIIIIIIIII<br>
llllllllll<br>
//////////<br>
</div>
<div id="c">
(subpixel)<br>
??????????<br>
||||||||||<br>
IIIIIIIIII<br>
llllllllll<br>
//////////<br>
</div>
<div id="d">
(none)<br>
??????????<br>
||||||||||<br>
IIIIIIIIII<br>
llllllllll<br>
//////////<br>
</div>
<script>
'use strict';
function add(container) {
let canvas = document.createElement('canvas');
const width = container.clientWidth;
canvas.style.width = `${width}px`;
const height = 40;
canvas.style.height = `${height}px`;
canvas.width = Math.floor(width * window.devicePixelRatio);
canvas.height = Math.floor(height * window.devicePixelRatio);
container.append(canvas);
let ctx = canvas.getContext('2d', {alpha: false});
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'black';
ctx.font = '12pt Arial';
ctx.fillText('\/!|hello world', 0, height / 2);
}
add(a);
add(b);
add(c);
add(d);
</script>