2014-03-05 1 views
4

html5에서 putImageData()를 사용하여 캔버스에 그릴 때 드로잉하는 픽셀 중 일부가 투명 (또는 반투명) 인 경우 캔버스의 오래된 픽셀을 영향을받지 않게하려면 어떻게해야합니까?putImageData(), 새 픽셀이 투명하면 오래된 픽셀을 유지하는 방법은 무엇입니까?

예 :

var imgData = context.createImageData(30,30); 
for(var i=0; i<imgData.data.length; i+=4) 
{ 
imgData.data[i]=255; 
imgData.data[i+1]=0; 
imgData.data[i+2]=0; 
imgData.data[i+3]=255; 
if((i/4)%30 > 15)imgData.data[i+3] = 0; 
} 
context.putImageData(imgData,0,0); 

30x30의 RECT의 우측 절반은 투명하다. 캔버스에 그려져있는 경우 오른쪽 절반 뒤에있는 픽셀이 제거됩니다 (또는 투명 해집니다). 나는 그들을 어떻게 지켜야합니까?

답변

5

당신은 반투명 오버레이 만들 getImageData를 사용할 수 있습니다

  • 당신이
  • 을 원하는대로
  • 픽셀을 수정 오프 스크린 캔버스에서 픽셀 데이터를 얻을 캔버스 오프 스크린
  • getImageData을 임시을 만듭니다
  • putImageData 화면 밖 캔버스의 픽셀
  • 화면 상 캔버스에 오프 스크린 캔버스를 그릴 때 drawImage를 사용하십시오.
  • http://jsfiddle.net/m1erickson/CM7uY/

    <!doctype html> 
    <html> 
    <head> 
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
    <style> 
        body{ background-color: ivory; } 
        canvas{border:1px solid red;} 
    </style> 
    <script> 
    $(function(){ 
    
        var canvas=document.getElementById("canvas"); 
        var context=canvas.getContext("2d"); 
    
        // draw an image on the canvas 
        var img=new Image(); 
        img.onload=start; 
        img.src="https://dl.dropboxusercontent.com/u/139992952/stack1/landscape1.jpg"; 
        function start(){ 
         canvas.width=img.width; 
         canvas.height=img.height; 
         context.drawImage(img,0,0); 
    
         // overlay a red gradient 
         drawSemiTransparentOverlay(canvas.width/2,canvas.height) 
    
        } 
    
        function drawSemiTransparentOverlay(w,h){ 
    
         // create a temporary canvas to hold the gradient overlay 
         var canvas2=document.createElement("canvas"); 
         canvas2.width=w; 
         canvas2.height=h 
         var ctx2=canvas2.getContext("2d"); 
    
         // make gradient using ImageData 
         var imgData = ctx2.getImageData(0,0,w,h); 
         var data=imgData.data; 
         for(var y=0; y<h; y++) { 
          for(var x=0; x<w; x++) { 
           var n=((w*y)+x)*4; 
           data[n]=255; 
           data[n+1]=0; 
           data[n+2]=0; 
           data[n+3]=255; 
           if(x>w/2){ 
            data[n+3]=255*(1-((x-w/2)/(w/2))); 
           } 
          } 
         } 
    
         // put the modified pixels on the temporary canvas 
         ctx2.putImageData(imgData,0,0); 
    
         // draw the temporary gradient canvas on the visible canvas 
         context.drawImage(canvas2,0,0); 
    
        } 
    
    
    }); // end $(function(){}); 
    </script> 
    </head> 
    <body> 
        <canvas id="canvas" width=200 height=200></canvas> 
    </body> 
    </html> 
    

    또는 좀 더 직접 영향을 할 수있는 선형 그라데이션을 사용하여 확인할 수 : 63,210

enter image description here

다음은 예제 코드와 데모입니다.

http://jsfiddle.net/m1erickson/j6wLR/

+0

감사를 재사용 할 수

  • 에 케이. – Mohsin

  • 2

    문제

    아시다시피, 명세서, 투명 이미지의 우측에 픽셀을 만들 것입니다

    if((i/4)%30 > 15)imgData.data[i+3] = 0; 
    

    그래서 뒤에 페이지에있는 다른 객체 그 픽셀 위치에서 캔버스를 통해 캔버스를 볼 수 있습니다. 그러나 캔버스 자체의 픽셀을 여전히 이전 픽셀 모두를 대체하는 context.putImageData으로 덮어 쓰는 중입니다. 추가 한 투명도로 인해 이전 픽셀이 표시되지 않습니다. putImageData의 결과는 캔버스의 이전 픽셀 위에 두 번째 픽셀 세트가 아니기 때문에 기존 픽셀을 대체하기 때문입니다.

    솔루션

    난 당신이되지 않은 데이터의 빈 세트로 시작되는 createImageData와 코드를 시작, 오히려 getImageData 당신에게 함께 일할 수있는 기존 데이터의 사본을 줄 것이다 것이 좋습니다. 그런 다음 조건문을 사용하여 보존하려는 이미지 부분을 덮어 쓰지 않도록 할 수 있습니다. 이것은 또한 당신의 기능을보다 효율적으로 만들 것입니다.

    var imgData = context.getImageData(30,30); 
    for(var i=0; i<imgData.data.length; i+=4) 
    { 
        if((i/4)%30 > 15) continue; 
        imgData.data[i]=255; 
        imgData.data[i+1]=0; 
        imgData.data[i+2]=0; 
        imgData.data[i+3]=255; 
    } 
    context.putImageData(imgData,0,0); 
    
    +0

    감사합니다. 맞습니다. getImageData()를 사용하여 이전 픽셀로 원하는 모든 작업을 수행 할 수 있지만 새 픽셀을 이전 픽셀과 혼합하는 수식이 필요합니다. 나는 하나를 시도하고 완벽했지만, 곧 for for loop (그림을 그리기)에서 이것을 사용하기 시작했을 때, 나는 무언가를 그릴 때 이상한 결과를 얻었습니다. – Mohsin

    0

    캔버스의 수정되지 않은 버전을 CRISP 자체에 복사하려고합니다. 나는 결국이 해결책을 생각해 냈다.

    var imageData = canvas.toDataURL(0, 0, w, h); 
    var tmp = document.createElement('img'); 
    tmp.style.display = 'none' 
    tmp.src = imageData; 
    document.body.appendChild(tmp); 
    ctx.drawImage(tmp, 30, 30); 
    

    무엇 일어나고 : 보이지 않는으로

  • 세트의 화상 데이터를 캔버스

    • 복사 화상 데이터 (에 보유

      https://jsfiddle.net/4Le454ak/1/

      복사 부이 코드에 그래도 돔에있다)

    • 그 그림을 그린다. 내가 필요 정확히 무엇을 사용하여 서로의 drawImage()에 캔버스 그리기 캔버스를 삭제하거나이 시점에서