在Html5中,从(0.5,0)到(0.5,600)绘制以在画布上获得1像素粗线。 0.5很奇怪?

时间:2010-09-07 10:09:46

标签: html5 canvas

我正在读一本关于Html5和关于画布的书,以下代码将生成1像素粗线...它使用0.5作为坐标。如果将其更改为0或10或某个整数,则这些线将为灰色,并且为2像素厚。这是为什么?这是我最近看到的最奇怪的事情......以前在Apple或Win32 API上的所有编程,它们都是整数坐标。

<!DOCTYPE html>

<body>
<canvas id="c" width="800" height="600"></canvas>
</body>

<script>

var c_canvas = document.getElementById("c")
var context = c_canvas.getContext("2d")

for (x = 0.5; x < 500; x += 10) {
  context.moveTo(x, 0)
  context.lineTo(x, 375)
}
context.strokeStyle = "#000"
context.stroke()


</script>

另一个奇怪的事情是,要获得1像素乘1像素的黑点,我必须在x上绘制0.5,但是使用整数表示y

for (x = 0.5; x < 500; x += 10) {
  context.moveTo(x, 0)
  context.lineTo(x, 1)
}

如果我使用以下内容,那么我会得到一个灰色的“更长点”

for (x = 0.5; x < 500; x += 10) {
  context.moveTo(x, 0.5)
  context.lineTo(x, 1.5)
}

4 个答案:

答案 0 :(得分:11)

谢谢MiKy。我还找到了一些解释:

https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors#A_lineWidth_example

这是相关内容:

  

获得清晰的线条需要了解如何抚摸路径。在   在下面的图像中,网格表示画布坐标网格。该   网格线之间的正方形是实际的屏幕像素。在第一个   在下面的网格图像中,填充从(2,1)到(5,5)的矩形。该   它们之间的整个区域(浅红色)落在像素边界上,所以   生成的填充矩形将具有清晰的边缘。

Crisp and Blurry lines example

  

如果考虑从(3,1)到(3,5)的路径,线宽为   1.0,你最终得到了第二张图片中的情况。要填充的实际区域(深蓝色)仅延伸到像素上的一半   路径的两边。必须渲染一个近似值,   这意味着那些像素只是部分遮蔽,结果   在整个区域(淡蓝色和深蓝色)被填充   颜色只有实际描边颜色的一半。这是什么   发生在前面示例代码中的1.0宽度行。

     

要解决此问题,您必须非常精确地创建路径。   知道1.0宽度线将延伸半个单元到任一侧   的路径,创建从(3.5,1)到(3.5,5)的路径导致   第三个图像中的情况 - 1.0线宽完全结束   精确填充单个像素垂直线。

答案 1 :(得分:6)

我不确定它与HTML5是一样的,但它看起来与Qt库处理绘画的方式非常相似。基本上,(0,0)和(1,1)坐标在左上角定义一个像素 - 因此它的中心位于(0.5,0.5)。

它与抗锯齿有关 - 如果你在(1,1)处“画”一个黑色像素,4个灰色像素实际上将被涂成灰色,介于(0,0)和(2,2)之间。在C++ GUI programming with Qt 4中了解详情。

答案 2 :(得分:2)

简而言之,像素无法分割。使用lineTo绘制1像素线时,该线以您指定的坐标为中心。如果width = 1且坐标是整数,则要求绘制一半像素的两半。

由于你无法打开半个像素,因此库会向两边的最近可分割像素舍入。

答案 3 :(得分:0)

当我再次使用画布重新开始时,我或多或少地与之斗争 - 你是使用“数学”线而不是屏幕上的线条。

正如其他人所提到的 - 从(1,1)到(1,10)的一条线在像素(0 / 0,1 / 1)之间开始,在(0 / 10,1 / 11)之间结束

因此它的1像素宽,1像素高。但是好一点点......

我的解决方案,如果您使用画布仅绘制“硬 - 整数 - 行”,例如创建一个控件,就是使用transform(1,0,0,1,0.5,0.5)(或transform(1,0,0,1,-0.5,-0.5)取决于你想用0或1来启动它)

(我用变换来确定,没有(a)或(d)再次让我的生活变得艰难)

在0到1之间的行上移动零​​(现在你知道我的昵称......)

这在我绘画(或必须绘制)“pixeled”

的所有情况下都能正常工作