簡體   English   中英

在HTML5畫布中移動裁剪的圖像

[英]Move cropped image in HTML5 canvas

如何在畫布內將裁剪后的圖像向下移動100px,向左移動50px? 包含的jsfiddle鏈接。

使用Javascript

// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');



// Create an image element
var img = document.createElement('IMG');

// When the image is loaded, draw it
img.onload = function () {

// Save the state, so we can undo the clipping
ctx.save();


// Create a shape, of some sort
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(100, 30);
ctx.lineTo(180, 10);
ctx.lineTo(200, 60);
ctx.arcTo(180, 70, 120, 0, 10);
ctx.lineTo(200, 180);
ctx.lineTo(100, 150);
ctx.lineTo(70, 180);
ctx.lineTo(20, 130);
ctx.lineTo(50, 70);
ctx.closePath();
// Clip to the current path
ctx.clip();


ctx.drawImage(img, 0, 0);

// Undo the clipping
ctx.restore();
}

// Specify the src to load the image
img.src = "http://i.imgur.com/gwlPu.jpg";

HTML

<canvas id="c" width="400" height="400"></canvas>

jsFiddle http://jsfiddle.net/dDUC3/3805/

首先,您應該在所需位置創建形狀,這將是合適的解決方案。

但是,在此階段,您可以使用getImageData()putImageData()方法來完成移動...

 // Grab the Canvas and Drawing Context var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); // Create an image element var img = document.createElement('IMG'); // When the image is loaded, draw it img.onload = function() { // Save the state, so we can undo the clipping ctx.save(); // Create a shape, of some sort ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 30); ctx.lineTo(180, 10); ctx.lineTo(200, 60); ctx.arcTo(180, 70, 120, 0, 10); ctx.lineTo(200, 180); ctx.lineTo(100, 150); ctx.lineTo(70, 180); ctx.lineTo(20, 130); ctx.lineTo(50, 70); ctx.closePath(); // Clip to the current path ctx.clip(); ctx.drawImage(img, 0, 0); // Undo the clipping ctx.restore(); move(50, 100); //move left: 50px, down: 100px } // Set cross origin for the image, as it's not hosted on local server img.crossOrigin = 'anonymous'; // Specify the src to load the image img.src = "http://i.imgur.com/gwlPu.jpg"; function move(left, down) { var croppedImage = ctx.getImageData(0, 0, 200, 200); ctx.clearRect(0, 0, canvas.width, canvas.height); //clear canvas ctx.putImageData(croppedImage, 0 + left, 0 + down); } 
 canvas { background: #CEF; } 
 <canvas id="c" width="400" height="400"></canvas> 

安全的畫布剪切和粘貼

在許多情況下,由於與ctx.getImageDatactx.getImageData圖像相關聯的跨源安全性違規,給出的答案將失敗。

直接復制並粘貼

如果將圖像移動為正方形區域或與原始圖像不重疊,則可以直接在畫布內復制。

ctx.drawImage(ctx.canvas, 0, 0, 200, 200, 100, 100, 200, 200);

直接剪切並粘貼

由於有些重疊需要清除,因此可以分為兩部分進行復制

// move bottom half
ctx.drawImage(ctx.canvas, 0, 100, 200, 100, 100, 200, 200, 100); 
// clear bottom half
ctx.clearRect(0, 100, 200, 100);
// move top half
ctx.drawImage(ctx.canvas, 0, 0, 200, 100, 100, 100, 200, 100); 
// lear top half
ctx.clearRect(0, 0, 200, 100);

但這還是有問題的。

一般剪切粘貼

理想的解決方案是創建一個臨時畫布來保存圖像,以便可以移動圖像。 如果畫布被交叉原點數據污染,則不會受到重疊的影響,也不會失敗。

function cutFromCanvas(ctx, x, y, w, h){
    const cut = document.createElement("canvas");
    cut.width = w;
    cut.height = h;
    cut.getContext("2d").drawImage(ctx.canvas, -x, -y, w, h, 0, 0, w, h);
    ctx.clearRect(x, y, w, h);
    return cut;
}

然后過去到新的位置,只需繪制圖像

  ctx.drawImage(cutFromCanvas(ctx, 0, 0 200, 200), 100, 100);

正如@gaand所說,最好的方法是將剪切形狀移動到應該的位置。 無需使用setTransform修改路徑聲明即可完成此操作。

 var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = document.createElement('IMG'); img.onload = function() { // move everything ctx.setTransform(1, 0, 0, 1, 100, 100); ctx.save(); ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 30); ctx.lineTo(180, 10); ctx.lineTo(200, 60); ctx.arcTo(180, 70, 120, 0, 10); ctx.lineTo(200, 180); ctx.lineTo(100, 150); ctx.lineTo(70, 180); ctx.lineTo(20, 130); ctx.lineTo(50, 70); ctx.closePath(); ctx.clip(); ctx.drawImage(img, 0, 0); // to restore the original matrix ctx.setTransform(1, 0, 0, 1, 100, 100); // but it's also restored here anyway... ctx.restore(); }; img.src = "http://i.imgur.com/gwlPu.jpg"; 
 canvas { background: lightblue } 
 <canvas id="c" width="500" height="300"></canvas> 

但是,如果您確實需要在繪制后將其移動,那么最好的方法是使用屏幕外的畫布,在該畫布上生成您的裁剪圖像,最后在可見的位置上將該屏幕外的畫布繪制在所需的位置:

 var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = document.createElement('IMG'); var clippedCanvas = document.createElement('canvas'); var clippedCtx = clippedCanvas.getContext('2d'); img.onload = function() { //prepare our offscreen canvas clippedCanvas.width = this.width; clippedCanvas.height = this.height; // generate the drawing on the offscreen ctx clippedCtx.save(); clippedCtx.beginPath(); clippedCtx.moveTo(10, 10); clippedCtx.lineTo(100, 30); clippedCtx.lineTo(180, 10); clippedCtx.lineTo(200, 60); clippedCtx.arcTo(180, 70, 120, 0, 10); clippedCtx.lineTo(200, 180); clippedCtx.lineTo(100, 150); clippedCtx.lineTo(70, 180); clippedCtx.lineTo(20, 130); clippedCtx.lineTo(50, 70); clippedCtx.closePath(); clippedCtx.clip(); clippedCtx.drawImage(img, 0, 0); // now we can our composed image anywhere in th visible canvas ctx.drawImage(clippedCanvas, 100,100); }; img.src = "http://i.imgur.com/gwlPu.jpg"; 
 canvas { background: lightblue } 
 <canvas id="c" width="500" height="300"></canvas> 

但是,對於一個鏡頭,您可能會發現聲明一個新的canvas元素很麻煩。 因此,第三個選擇是利用globalCompositeOperation 'copy'它使我們能夠在其自身上繪制畫布而不保留先前的狀態:

 var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = document.createElement('IMG'); img.onload = function() { ctx.save(); ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 30); ctx.lineTo(180, 10); ctx.lineTo(200, 60); ctx.arcTo(180, 70, 120, 0, 10); ctx.lineTo(200, 180); ctx.lineTo(100, 150); ctx.lineTo(70, 180); ctx.lineTo(20, 130); ctx.lineTo(50, 70); ctx.closePath(); ctx.clip(); ctx.drawImage(img, 0, 0); ctx.restore(); // the magic ctx.globalCompositeOperation = 'copy'; // draw the canvas over itself, at 100 100 ctx.drawImage(canvas, 100,100); }; img.src = "http://i.imgur.com/gwlPu.jpg"; 
 canvas { background: lightblue } 
 <canvas id="c" width="500" height="300"></canvas> 

現在,我們已經發現了gCO,我們甚至可以刪除此裁剪操作:

 var canvas = document.getElementById('c'); var ctx = canvas.getContext('2d'); var img = document.createElement('IMG'); img.onload = function() { // move everything ctx.setTransform(1,0,0,1,100,100); ctx.beginPath(); ctx.moveTo(10, 10); ctx.lineTo(100, 30); ctx.lineTo(180, 10); ctx.lineTo(200, 60); ctx.arcTo(180, 70, 120, 0, 10); ctx.lineTo(200, 180); ctx.lineTo(100, 150); ctx.lineTo(70, 180); ctx.lineTo(20, 130); ctx.lineTo(50, 70); // we draw this shape ctx.fill(); // new pixels will be drawn only where they do overlap with existing ones ctx.globalCompositeOperation = 'source-in'; ctx.drawImage(img, 0, 0); // restore the matrix ctx.setTransform(1,0,0,1,0,0); }; img.src = "http://i.imgur.com/gwlPu.jpg"; 
 canvas { background: lightblue } 
 <canvas id="c" width="500" height="300"></canvas> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM