2012-03-02 53 views
29

我在畫布上使用了clip()函數。如何在Chrome Windows下的HTML5畫布中反鋸齒clip()邊緣?

結果: using canvas clip in various browsers

正如你可以看到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> 
+0

我也遇到了這個問題。我所做的就是在圖像的相同位置繪製一個圓圈,在它後面,半徑爲1或2 px。保持顏色相似,然後去「反鋸齒」圖像剪輯。 – Automatico 2012-07-23 14:31:13

回答

2
從答案

Can I turn off antialiasing on an HTML <canvas> element?看來,它是針對特定瀏覽器。它甚至是google代碼鉻項目上的一個活躍bug report。對不起,現在看起來你運氣不好。

+1

現在,錯誤修復處於[chrome dashboard](https://www.chromestatus.com/features/4871530282483712)的開發狀態。 正如[問題](https://code.google.com/p/chromium/issues/detail?id=422984)中所述,其他瀏覽器(IE,Firefox,Safari)'clip()'是反鋸齒的。 – sapics 2015-09-25 06:06:22

-1

使用svg剪輯。像魅力一樣工作,但不便於使用。

5

我遇到了與Chrome和clip()相同的問題。

在我的情況下,我通過設置畫布globalCompositeOperation實現了更好的瀏覽器兼容性。

context.globalCompositeOperation = 'source-atop'; 

所以在這種情況下繪製你的形狀,一個圓圈。然後切換到'source-atop'並繪製你的小貓圖像。

請注意,這是基本繪圖的快速修復,並假定爲空白畫布。之前的畫布繪製會影響您的剪輯。

+0

這個解決方案表現非常好,謝謝。剪輯的一個弧和中風的一個弧。簡單。我相信對於這個問題,臨時畫布解決方案太複雜和緩慢,除非你有不想要中風的問題。 – mattdlockyer 2013-07-23 19:40:34

+0

當我通過畫布運行視頻時,我能夠應用此功能以及「背部畫布」技術,以減少令人討厭的鋸齒狀邊緣:http://codepen.io/paceaux/pen/egLOeR 謝謝分享。 – paceaux 2017-02-10 19:18:12

12

我對此的修復是在繪製圖像後在相同的半徑處繪製薄(2px)的白色筆劃。它很好地覆蓋了別名,並且在瀏覽器中看起來很好。

+0

這麼棒的主意!謝謝!! – Keith 2013-02-17 22:37:17

+0

我一直在努力今天超過一個小時,這樣一個簡單而神奇的解決方案:) – trueicecold 2014-08-13 14:53:44

+0

是的,這,CLEVER,<3! – 2014-09-05 22:33:43

22

如果您正在執行復雜的分層繪製,則可以使用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, ...); 

我們在臨時畫布中這樣做的原因是,目標輸入是一個非常具有破壞性的操作。如果你已經在主畫布上繪製了一些東西(也許你在背景中放下了一個很好的漸變),然後想要繪製剪裁的圖像,剪裁圓也會剪掉你已經繪製的所有東西。當然,如果你的特定情況比較簡單(也許你想繪製的圖像是一個剪輯圖像),那麼你可以放棄臨時畫布。

可以玩弄於my demo page不同的修剪模式。底行(帶漸變)對你來說並不是太有用,但最上面的一行(與圓形和方形)更相關。

編輯

哎呦,我不小心forked your JSFiddle來演示該技術。

+0

你先生,救了我的一天! – enyce12 2014-07-10 14:55:59

+0

謝謝你!其作品!!! – 2016-05-16 17:54:48