仅保存HTML画布的某个部分

时间:2015-08-27 18:08:37

标签: javascript html5 canvas

是否可以仅保存或导出画布的某个部分而不是整个画布?

http://i.stack.imgur.com/hmvYh.jpg

此刻,当我保存文件时,我得到了我在网站上的整个画布元素的构图加上透明背景(上面例子中的浅蓝色)。我想得到的只是灰色区域(可以由几个图像和文本元素组成)。

2 个答案:

答案 0 :(得分:6)

是的,你可以。这是the JSFiddle

首先,您需要在画布中拍摄clipping图像。这很简单。我制作了另一个画布(隐藏的画布)并使用了context.drawImage

var hidden_ctx = hidden_canvas.getContext('2d');

hidden_ctx.drawImage(
    MainCanvas,
    startClippingX,
    startClippingY,
    clippingWidth,
    clippingHeight,
    pasteX,
    pasteY,
    pasteWidth,
    pasteHeight
);

现在,我们需要来自此画布的数据URL,以便我们可以下载内容。为此,我们将使用canvas.toDataURL方法。

var data_url = hidden_canv.toDataURL("image/png");

现在,我们需要做的就是制作一个下载链接(a元素,href属性为data_url,我们已经完成了!

答案 1 :(得分:5)

假设您有一个名为oldCanvas的画布,并且您希望保存宽度为w且高度为h的矩形区域,其左上角位于x, y

首先制作宽度为canvas且高度为w的新h元素:

var newCanvas = document.createElement('canvas');
newCanvas.width = w;
newCanvas.height = h;

现在将矩形区域复制到新画布:

var newContext = newCanvas.getContext('2d');
newContext.drawImage(oldCanvas, x, y, w, h, 0, 0, w, h);

最后,使用toDataUrl()或以前用于保存整个画布的任何方法保存新画布。

例如,您可以使用新画布制作图像:

var newImage = document.createElement('img');
newImage.src = newCanvas.toDataURL();

然后将新图像附加到网页:

document.body.appendChild(newImage);

或者您可能要将容器div附加到其中。

在任何情况下,一旦图像在文档中,您可以右键单击它并像往常一样保存。

我已在以下代码段中实现了此方法。当你运行它时,将随机绘制一个画布。在画布上单击并拖动以选择要下载的区域。右侧会出现一个可下载的新图像。



// Returns a random RGB string (RGBA if alpha is true).
function randomColor(alpha) {
  var rgb = [
    Math.floor(Math.random() * 255),
    Math.floor(Math.random() * 255),
    Math.floor(Math.random() * 255)
  ];
  if (alpha) {
    rgb.push(Math.random());
  }
  return 'rgb' + (alpha ? 'a' : '') + '(' + rgb.join(', ') + ')';
}

// Makes a random picture for use in the demonstration.
function makeCanvas() {
  var canvas = document.getElementById('oldCanvas'),
      context = canvas.getContext('2d'),
      width = canvas.width = 400,
      height = canvas.height = 500;
  context.fillStyle = randomColor();
  context.fillRect(0, 0, width, height);
  for (var i = 0; i < 200; ++i) {
    var x = Math.floor(Math.random() * width),
        y = Math.floor(Math.random() * height),
        w = Math.floor(Math.random() * width/5),
        h = Math.floor(Math.random() * height/5);
    context.fillStyle = randomColor(true);
    if (Math.floor(Math.random() * 2) === 0) {
      context.fillRect(x - w / 2, y - h / 2, w, h);
    } else {
      context.beginPath();
      context.arc(x, y, w, 0, 2 * Math.PI);
      context.closePath();
      context.fill();
    }
  }
  return canvas;
};

window.onload = function () {
  var oldCanvas = makeCanvas(),
      oldContext = oldCanvas.getContext('2d'),
      targetImage = document.getElementById('targetImage'),
      downloadContainer = document.getElementById('downloadContainer'),
      selectCanvas = document.getElementById('selectCanvas'),
      selectContext = selectCanvas.getContext('2d'),
      width = selectCanvas.width = oldCanvas.width,
      height = selectCanvas.height = oldCanvas.height;
  selectContext.fillStyle = '#000';
  downloadContainer.style.left = width + 25 + 'px';
  var clipCanvas = document.createElement('canvas'),
      clipContext = clipCanvas.getContext('2d');
  downloadContainer.appendChild(clipCanvas);
  selectCanvas.onmousedown = function (event) {
    var x0 = Math.max(0, Math.min(event.clientX, width)),
        y0 = Math.max(0, Math.min(event.clientY, height));
    targetImage.style.display = 'none';
    function update(event) {
      var x = Math.max(0, Math.min(event.clientX, width)),
          y = Math.max(0, Math.min(event.clientY, height)),
          dx = x - x0, w = Math.abs(dx),
          dy = y - y0, h = Math.abs(dy);
      selectContext.clearRect(0, 0, width, height);
      selectContext.fillRect(x0, y0, dx, dy);
      clipCanvas.width = w;
      clipCanvas.height = h;
      if (w*h == 0) {
        downloadContainer.style.visibility = 'hidden';
      } else {
        downloadContainer.style.visibility = 'visible';
        clipContext.drawImage(oldCanvas,
          x0 + Math.min(0, dx), y0 + Math.min(0, dy), w, h,
          0, 0, w, h);
        downloadContainer.style.visibility = (w*h == 0 ? 'hidden' : 'visible');
        downloadContainer.style.top = Math.min(y0, y) + 'px';
      }
    };
    update(event);
    selectCanvas.onmousemove = update;
    document.onmouseup = function (event) {
      selectCanvas.onmousemove = undefined;
      document.onmouseup = undefined;
      targetImage.src = clipCanvas.toDataURL();
      targetImage.style.display = 'block';
    };
  };
};
&#13;
body, div, canvas, img {
  margin: 0;
  padding: 0;
}
#targetImage {
  display: none;
  position: absolute;
  left: 0;
  top: 0;
}
canvas {
  display: block;
}
#oldCanvas, #selectCanvas, #downloadContainer {
  position: fixed;
}
#downloadContainer {
  visibility: hidden;
}
#downloadContainer .label {
  position: absolute;
  width: 500px;
  bottom: -20px;
  font-family: sans-serif;
  font-size: 17px;
  color: #444;
}
#selectCanvas {
  opacity: 0.5;
  cursor: default;
}
&#13;
<canvas id="oldCanvas"></canvas>

<canvas id="selectCanvas"></canvas>

<div id="downloadContainer">
  <div class="label"> right-click above to download this image </div>
  <img id="targetImage">
</div>
&#13;
&#13;
&#13;