3

是否可以创建具有更好笔画且没有“模糊”边框的椭圆/椭圆,类似于:

我可以以某种方式在椭圆周围创建更清晰的笔划线,还是我必须忍受那个“模糊”的边界? 在此处输入图像描述

4

3 回答 3

3

!你能行的 !通过进行后处理:

1)使用 globalCompositeOperation :

编辑:是的,但不是:至少在 Chrome 上,'destination-in' 与规范不匹配:源用于计算目标颜色,因此我们不能从阴影中获得单一颜色。
(我尝试了 JSBin:http: //jsbin.com/ecipiq/4/

或者

2)使用 getImageData 和性能数组:

  • 在临时画布中绘制边框
  • 画布的getImageData
  • 获取底层数据的 Uint32Array 或 Uint8Array 视图
  • 在数组内线性循环:如果值 > 阈值将其设置为边框颜色
  • 在目标画布上绘制椭圆的填充
  • putImageData 在目标画布上。

哪一个 ?

  • 第二个不需要 globalCompositeOperation 工作。
    但是在大多数浏览器上(全部?)get/put ImageData 都慢得要命,仅凭这一事实就可能使
    解决方案无效。
    好消息是您可以精确地决定如何取消抗锯齿。

其他 StackOverflow 成员可能对这一切都有见解。

这些解决方案中的任何一个都将比手写的非锯齿椭圆函数快得多。

第一个解决方案的有用链接:http:
//www.html5rocks.com/en/tutorials/webgl/typed_arrays/

让您更快入门的备注:
您可以通过以下方式在 ImageData 上获得 UInt32Array 视图:

var myGetImageData = myTempCanvas.getImageData(0,0,sizeX, sizeY);
sourceBuffer32     = new UInt32Array(myGetImageData.data.buffer);

然后 sourceBuffer32[i] 包含打包成一个无符号 32 位 int 的红色、绿色、蓝色和透明度。将其与 0 进行比较以了解像素是否为非黑色( != (0,0,0,0) )

或者您可以使用 Uint8Array 视图更精确:

var myGetImageData = myTempCanvas.getImageData(0,0,sizeX, sizeY);
sourceBuffer8     = new Uint8Array(myGetImageData.data.buffer);

如果您只处理灰色阴影,则 R=G=B,因此请注意

sourceBuffer8[4*i]>Threshold

您可以使用 UInt32Array 视图一次性将第 i 个像素设置为黑色:

sourceBuffer32[i]=(255<<24)||(255<<16)||(255<<8);

从这个例子中,你肯定能够弄清楚如何处理灰色/黑色以外的其他颜色。

于 2013-01-20T21:08:07.150 回答
2

简短的回答是否定的,对不起!

该规范没有评论浏览器必须使用(或不使用)的抗锯齿方法,因此浏览器之间会有所不同。不同版本的 Chrome(尤其是如果您使用 chrome beta 或开发者频道)总是在这个问题上出现问题。

在规范中对此进行了一些讨论,但没有采取任何行动,除了现在可以选择关闭图像平滑的图像(上下文的imageSmoothingEnabled属性)。但是,这绝不适用于路径。

不幸的是,一种解决方案只能在最狭窄的情况下工作:如果您的椭圆是固定的,则在 Firefox(可以说是具有最平滑抗锯齿的浏览器)中创建它们并从中生成图像,然后在所有浏览器上绘制图像.

简而言之,如果您想要在所有浏览器中使用相同的像素形状,则必须使用图像,目前没有其他方法。

于 2013-01-20T18:58:23.610 回答
2

是的你可以!这是调用context.stroke()25 次而不是一次的结果:

非模糊椭圆

对比一下,原文如下:

模糊的椭圆

于 2013-01-20T19:26:28.063 回答