如何将画布的一部分捕捉为位图

8
我想捕获画布的一小部分作为位图。这样我就可以在那个区域绘制另一个位图后替换它。完成位图后,我想用原始碎片替换我绘制的画布上的小块。

谢谢!

3个回答

9
drawImage() 方法允许您使用现有的画布作为源。它还允许您指定要绘制的源“图像”的子区域。您还可以通过编程方式创建新的画布元素。将它们组合起来,您就可以创建自己的屏幕外缓冲区,并在它们之间进行位块传输,而无需通过 getImageData() / putImageData() 或数据URL 进行操作。
我已经在网上放了一个 此类示例
请注意,虽然示例恰好将动态创建的画布附加到文档中以便您可以看到它(源代码的第29行),但这并非必要。在文档中创建的画布元素无论是否连接到层次结构都可以使用。
简而言之:
function copyCanvasRegionToBuffer( canvas, x, y, w, h, bufferCanvas ){
  if (!bufferCanvas) bufferCanvas = document.createElement('canvas');
  bufferCanvas.width  = w;
  bufferCanvas.height = h;
  bufferCanvas.getContext('2d').drawImage( canvas, x, y, w, h, 0, 0, w, h );
  return bufferCanvas;
}

编辑:我对比了这种技术和getImageData/putImageData;如果速度很重要,请使用drawImage来 blitting 区域。以下是我看到的:


(来源:phrogz.net)

在 OS X 上的 2.8GHz Core i7 MacBook Pro 上保存和恢复一个 125x180 区域 10,000 次所进行的基准测试。你的结果可能会有所不同。特别是保存/恢复较大或较小的区域可能会导致不同的相对性能。


如果您需要长期保存画布的区域(序列化并发送到服务器),则 getImageData()toDataURL() 是您的好帮手。 - Phrogz
你是如何进行基准测试的?我的意思是,你使用了哪些工具? - user372551
@Avinash 请查看基准测试页面。(结果将显示在日志中,有些名称会让人感到困惑。) - Phrogz

8
你可以使用 .getImageData().putImageData() 来实现此功能。 示例
var canvas, ctx, img, imgd, col;
window.onload = function () {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    col = {
        0: '#000',
        .25: '#0099f9',
        .55: '#03f',
        1: '#000'
    };
    img = document.getElementById('img');
    var w = h = canvas.width = canvas.height = 200;

    var grad = ctx.createRadialGradient(w / 2, w / 2, 0, w / 2, w / 2, h);
    for (var i in col) {
        grad.addColorStop(i, col[i]); //just a funny mess, please don't bother :)
    }

    ctx.fillStyle = grad;
    ctx.fillRect(0, 0, w, h);
    imgd = ctx.getImageData(50, 50, 20, 20); //caching the image Data

}

function draw() {
    ctx.drawImage(img, 50, 50, 20, 20); //drawing Image on to canvas
}

function redraw() {
    ctx.putImageData(imgd, 50, 50, 20, 20); //redraw the cached Image Data
}

这里有一个简单的在线示例,只需要你就可以使用 :)

在这里试用


1
getImageData()和putImageData()是你应该这样做的正确方式,而不是使用隐藏元素的hack方法,因为这会利用API的低级范围,所以对于这个答案表示赞赏。 :) - SikoSoft

2

在这里看一下类似的问题 如何在本地将一个画布的内容复制到另一个画布中

我建议写一些像这样的东西

var canvas1 = document.getElementById('canvas1');
var src     = canvas1.toDataURL("image/png"); // cache the image data source`

将图像保存在变量中,然后稍后检索它

var img     = document.createElement('img'); // create a Image Element
img.src     = src;   //image source
var ctx1    = canvas1.getContext('2d');
ctx2.drawImage(img, 0, 0);  // drawing image onto second canvas element

摘自这里


我明白你的意思,但我只想将画布中的一个小正方形捕捉到位图中,而不是整个画布。 - David C. Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接