2014-09-26 118 views
3

我有以下腳本複製圖像數據的更快速的方法

// copy image data to secondary canvas 
var pixelData = contextSource.getImageData(x - (lineWidth/2), y - (lineWidth/2), lineWidth, lineWidth); 
var tmpCanvas = document.createElement('canvas'); 
tmpCanvas.width = tmpCanvas.height = lineWidth; 
var tmpContext = tmpCanvas.getContext('2d'); 

tmpContext.putImageData(pixelData, 0, 0); 

contextDest.save(); 
contextDest.arc(x, y, (lineWidth/2), 0, 2*Math.PI); 
contextDest.clip(); 
contextDest.drawImage(tmpCanvas, x - (lineWidth/2), y - (lineWidth/2)); 
contextDest.restore(); 

腳本從帆布源時鼠標移動在源採樣的圖像數據,然後將其複製到目的地。該腳本運行良好,但有點慢。這是當我將鼠標指針移動一點時的結果。

enter image description here

有沒有比我更快的方法?請幫助

+0

基本上,當你不喜歡的東西上面,你不臨摹圓。你複製一行的開始/結束行是那些圈子。 – Banana 2014-09-26 08:37:15

+0

[這裏](http://jsfiddle.net/TheBanana/1rrpjvsr/)就是一個例子,我的意思是,我希望它有幫助 – Banana 2014-09-26 09:44:05

回答

3

enter image description here

@Banana好點。

代替繪圖的只是鼠標的位置,嘗試連接位置成一單一連續線..

如果你想在你的插圖圓潤的效果,你可以設置:

context.lineCap='round'; 
context.lineJoin='round'; 

至於掩蓋更快...

掩蓋你的形象更快的方式是:

  • 在第二個畫布上繪製單行。
  • 使用合成來使所有新繪製僅在現有像素不透明的情況下可見。這種合成是'源內',並使用:context.globalCompositeOperation='source-in'
  • 將您的圖像繪製到第二個畫布上。圖像將只顯示該行的位置。

使用合成是快得多,因爲合成是硬件加速並通過瀏覽器優化。

那合成的代碼可能是這樣的:

function draw(){ 
    // clear the second canvas 
    ctx1.clearRect(0,0,cw,ch); 

    // draw your continuous line 
    ctx1.beginPath(); 
    ctx1.moveTo(points[0].x,points[0].y); 
    for(var i=1;i<points.length;i++){ 
     p=points[i]; 
     ctx1.lineTo(p.x,p.y); 
    } 
    ctx1.stroke(); 

    // set compositing so new draws only appear in 
    // existing opaque pixels 
    ctx1.globalCompositeOperation='source-in'; 

    // draw the image 
    // the image will only be visible in the exising line 
    ctx1.drawImage(img,0,0); 

    // be tidy! return compositing to its default mode 
    ctx1.globalCompositeOperation='source-over'; 
} 

下面是一個例子,演示:

var canvas1=document.getElementById("canvas1"); 
 
var ctx1=canvas1.getContext("2d"); 
 

 
var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var $canvas=$("#canvas"); 
 
var canvasOffset=$canvas.offset(); 
 
var offsetX=canvasOffset.left; 
 
var offsetY=canvasOffset.top; 
 
var scrollX=$canvas.scrollLeft(); 
 
var scrollY=$canvas.scrollTop(); 
 

 
var isDown=false; 
 
var startX; 
 
var startY; 
 

 
var points=[]; 
 
var cw,ch; 
 

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/tempHouse%201.jpg"; 
 
function start(){ 
 
    cw=canvas.width=canvas1.width=img.width; 
 
    ch=canvas.height=canvas1.height=img.height; 
 

 
    ctx1.lineCap = "round"; 
 
    ctx1.lineJoin = "round"; 
 
    ctx1.lineWidth=20; 
 

 
    ctx.drawImage(img,0,0); 
 

 
    $("#canvas").mousedown(function(e){handleMouseDown(e);}); 
 
    $("#canvas").mousemove(function(e){handleMouseMove(e);}); 
 
    $("#canvas").mouseup(function(e){handleMouseUp(e);}); 
 
    $("#canvas").mouseout(function(e){handleMouseOut(e);}); 
 
} 
 

 

 
function draw(){ 
 
    // clear the second canvas 
 
    ctx1.clearRect(0,0,cw,ch); 
 

 
    // draw your continuous line 
 
    ctx1.beginPath(); 
 
    ctx1.moveTo(points[0].x,points[0].y); 
 
    for(var i=1;i<points.length;i++){ 
 
    p=points[i]; 
 
    ctx1.lineTo(p.x,p.y); 
 
    } 
 
    ctx1.stroke(); 
 

 
    // set compositing so new draws only appear in 
 
    // existing opaque pixels 
 
    ctx1.globalCompositeOperation='source-in'; 
 

 
    // draw the image 
 
    // the image will only be visible in the exising line 
 
    ctx1.drawImage(img,0,0); 
 

 
    // be tidy! return compositing to its default mode 
 
    ctx1.globalCompositeOperation='source-over'; 
 
} 
 

 

 
function handleMouseDown(e){ 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 
    mouseX=parseInt(e.clientX-offsetX); 
 
    mouseY=parseInt(e.clientY-offsetY); 
 
    points.length=0; 
 
    points.push({x:mouseX,y:mouseY}); 
 
    isDown=true; 
 
} 
 

 
function handleMouseUp(e){ 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 
    isDown=false; 
 
    draw(); 
 
} 
 

 
function handleMouseOut(e){ 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 
    mouseX=parseInt(e.clientX-offsetX); 
 
    mouseY=parseInt(e.clientY-offsetY); 
 
    points.push({x:mouseX,y:mouseY}); 
 
    isDown=false; 
 
    draw(); 
 
} 
 

 
function handleMouseMove(e){ 
 
    if(!isDown){return;} 
 
    e.preventDefault(); 
 
    e.stopPropagation(); 
 
    mouseX=parseInt(e.clientX-offsetX); 
 
    mouseY=parseInt(e.clientY-offsetY); 
 
    points.push({x:mouseX,y:mouseY}); 
 
    draw(); 
 
}
body{ background-color: ivory; } 
 
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<canvas id="canvas" width=300 height=300></canvas><br> 
 
<canvas id="canvas1" width=300 height=300></canvas>

+1

哇真棒!這是我尋找的..我會嘗試這個肯定的。非常感謝,你救了我的一天 – 2014-09-27 00:19:41