【问题标题】:How to anti-alias clip() edges in html5 canvas under Chrome Windows?如何在 Chrome Windows 下的 html5 画布中消除锯齿 clip() 边缘?
【发布时间】:2012-03-21 03:08:39
【问题描述】:

我在画布上使用 clip() 函数。

结果:

您可以看到 chrome 版本的边缘有可怕的锯齿/锯齿。我该如何解决这个问题?

要重现的代码:

http://jsfiddle.net/ZRA76/

<canvas id="test" width="300" height="300"></canvas>​

<script type="text/javascript">
    cv = document.getElementById("test");
    ctx = cv.getContext("2d");

    var im = new Image();
    im.onload = function () {
        ctx.beginPath();
        ctx.arc(110, 110, 100, 0, 2*Math.PI, true);
        ctx.clip();
        ctx.drawImage(im, 0, 0);
    }
    im.src = "http://placekitten.com/300/300";
</script>

【问题讨论】:

  • 我也遇到了这个问题。我所做的是在与图像相同的位置画一个圆,在它后面,半径大 1 或 2 px。保持颜色相似,“抗锯齿”图像剪辑就完成了。

标签: html google-chrome html5-canvas clip


【解决方案1】:

如果您要进行复杂的分层绘图,则可以使用 globalCompositeOperation 在第二个临时画布中模拟剪辑。然后,您可以使用 drawImage 将临时画布复制回原始画布。我不能保证这种方法的性能,但这是我知道的唯一获得你想要的方法。

//set-up - probably only needs to be done once
var scratchCanvas = document.createElement('canvas');
scratchCanvas.width = 100;
scratchCanvas.height = 100;
var scratchCtx = scratchCanvas.getContext('2d');


//drawing code
scratchCtx.clearRect(0, 0, scratchCanvas.width, scratchCanvas.height);

scratchCtx.globalCompositeOperation = 'source-over'; //default

//Do whatever drawing you want. In your case, draw your image.
scratchCtx.drawImage(imageToCrop, ...);


//As long as we can represent our clipping region as a single path, 
//we can perform our clipping by using a non-default composite operation.
//You can think of destination-in as "write alpha". It will not touch
//the color channel of the canvas, but will replace the alpha channel.
//(Actually, it will multiply the already drawn alpha with the alpha
//currently being drawn - meaning that things look good where two anti-
//aliased pixels overlap.)
//
//If you can't represent the clipping region as a single path, you can
//always draw your clip shape into yet another scratch canvas.

scratchCtx.fillStyle = '#fff'; //color doesn't matter, but we want full opacity
scratchCtx.globalCompositeOperation = 'destination-in';
scratchCtx.beginPath();
scratchCtx.arc(50, 50, 50, 0, 2 * Math.PI, true);
scratchCtx.closePath();
scratchCtx.fill();


//Now that we have a nice, cropped image, we can draw it in our
//actual canvas. We can even draw it over top existing pixels, and
//everything will look great!

ctx.drawImage(scratchCanvas, ...);

我们在草稿画布中执行此操作的原因是,destination-in 是一个非常具有破坏性的操作。如果您已经在主画布中绘制了一些东西(也许您在背景中放置了一个漂亮的渐变),然后想要绘制一个剪裁的图像,那么剪裁圆也会剪掉您已经绘制的所有内容。当然,如果您的特殊情况比较简单(也许您想要绘制的只是一张剪裁的图像),那么您可以放弃草稿画布。

您可以在my demo page 上使用不同的剪辑模式。底行(带有渐变)对您来说不太有用,但顶行(带有圆形和正方形)更相关。

编辑

哎呀,我不小心forked your JSFiddle演示了这个技巧。

【讨论】:

  • 先生,您救了我的命!
【解决方案2】:

我的解决方法是在绘制图像后在相同半径处绘制一个细 (2px) 的白色笔触。它很好地掩盖了别名,并且在浏览器中看起来很好。

【讨论】:

  • 好主意!谢谢!!
  • 我今天已经为此苦苦挣扎了一个多小时,这样一个简单而神奇的解决方案:)
  • 是的,这,聪明,
【解决方案3】:

我在 Chrome 和 clip() 中遇到了同样的问题。

在我的情况下,我通过设置画布 globalCompositeOperation 实现了更好的浏览器兼容性。

context.globalCompositeOperation = 'source-atop';

所以画出你的形状,在这种情况下是一个圆圈。然后切换到“source-atop”并绘制你的小猫图像。

请注意,这是基本绘图的快速修复,并假定画布为空白。以前的画布绘图会影响您的剪辑。

【讨论】:

  • 这个解决方案效果很好,谢谢。一条弧线用于剪辑,一条弧线用于笔划。简单的。我相信草稿画布解决方案对于这个问题来说太复杂和太慢了,除非你有一些不想要中风的问题。
【解决方案4】:

Can I turn off antialiasing on an HTML <canvas> element? 的答案看来,它是特定于浏览器的。它甚至是 google code chromium 项目中的一个活跃的bug report。抱歉,看来你现在运气不好。

【讨论】:

  • 现在,chrome dashboard 中的错误修复处于开发状态。正如Issues 中所写,其他浏览器(IE、Firefox、Safari)clip() 是抗锯齿的。
【解决方案5】:

使用 svg 剪辑。像魅力一样工作,但使用起来不太方便。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多