2012-03-02 3 views
29

캔버스에서 clip() 함수를 사용하고 있습니다.Chrome Windows에서 html5 캔버스의 클립에() 앤티 앨리어스를 적용하는 방법은 무엇입니까?

결과 : using canvas clip in various browsers

당신은 크롬 버전이 가장자리를 따라 무서운 계단 현상/앨리어싱을 가지고 볼 수 있듯이. 이 문제를 어떻게 해결할 수 있습니까?

코드 재현 :

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 배 큰 이미지와 동일한 위치에 원을 그리는 것입니다. 색상을 비슷하게 유지하고 "안티 앨리어싱 된"이미지 클립을 놓습니다. – Automatico

답변

2

Can I turn off antialiasing on an HTML <canvas> element?에 브라우저 특정 않은 것 같습니다. Google 코드 크롬 프로젝트에서 활성화 된 bug report입니다. 죄송 합니다만, 지금은 운이 다한 것 같습니다.

+1

버그 수정은 [chrome dashboard] (https://www.chromestatus.com/features/4871530282483712)의 개발 상태입니다. [Issues] (https://code.google.com/p/chromium/issues/detail?id=422984)에 쓰여 있듯이, 브라우저 (IE, Firefox, Safari)의'clip()'은 앤티 엘리 어싱되었습니다. – sapics

-1

svg 클립을 사용하십시오. 매력처럼 작동하지만 사용하기에 편리하지는 않습니다.

5

Chrome과 clip()에서 동일한 문제가 발생했습니다.

내 경우에는 canvas globalCompositeOperation을 설정하여 브라우저 호환성을 향상 시켰습니다.

context.globalCompositeOperation = 'source-atop'; 

이 경우 원 모양을 그립니다. 그런 다음 'source-atop'로 전환하고 새끼 고양이 이미지를 그립니다.

참고 :이 그림은 기본 그림에 대한 빠른 수정이며 빈 캔버스를 사용합니다. 이전 캔버스 그리기가 클립에 영향을줍니다.

+0

이 솔루션은 매우 잘 수행됩니다. 감사합니다. 클립에 대한 하나의 호와 획에 대한 하나의 호입니다. 단순한. 나는 스크래치 캔버스 솔루션이 뇌졸중을 원하지 않는다면 어떤 문제가 없다면이 문제에 대해 너무 복잡하고 느릴 것이라고 생각합니다. – mattdlockyer

+0

캔버스를 통해 비디오를 실행할 때 불쾌한 고르지 않은 가장자리를 줄이기 위해 이것을 "백 캔버스"기술과 함께 적용 할 수있었습니다. http://codepen.io/paceaux/pen/egLOeR 고맙습니다 나누는. – paceaux

12

이 문제를 해결하려면 이미지를 그린 후 동일한 반경에 얇은 (2 픽셀) 흰색 선을 그립니다. 그것은 앨리어싱을 멋지게 덮고 브라우저에서 잘 어울립니다.

+0

그런 좋은 생각이야! 감사!! – Keith

+0

저는 한 시간 이상이 오늘과 같은, 간단하고 놀라운 솔루션을 고민해 왔습니다 :) – trueicecold

+0

예, 이걸, CLEVER, <3! –

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, ...); 

우리가 스크래치 캔버스에서이 작업을 수행하는 이유는 destination-in이 꽤 파괴적인 작업이라는 것입니다. 이미 배경에 멋진 그라디언트를 넣은 다음 주름 잡은 이미지를 그리기 위해 주 캔버스에 일부 작업을 이미 수행 한 경우 클리핑 원이 사용자가 이미 그린 모든 것을 잘라냅니다. 물론, 특정 상황이 더 간단하다면 (아마도 여러분이 그리려는 모든 것이 잘린 이미지입니다), 그러면 여러분은 스크래치 캔버스를 포기할 수 있습니다.

my demo page에서 다른 클리핑 모드로 재생할 수 있습니다. 맨 아래 행 (그라디언트 포함)은 너에게별로 유용하지 않지만 맨 위 행 (원과 사각형 포함)은 훨씬 더 적합합니다.

편집

으악, 내가 실수로 forked your JSFiddle 기술을 설명합니다.

+0

너는 선생님, 저의 하루를 구했습니다! – enyce12

+0

고마워요! 그것은 작동합니다! –

관련 문제