Save only a certain part of an HTML canvas

后端 未结 2 1375
一个人的身影
一个人的身影 2021-01-05 17:10

Is it possible to save or export only a certain part of the canvas rather than the whole canvas?

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

At the moment, when I sav

相关标签:
2条回答
  • 2021-01-05 17:36

    Yes you can. Here is the JSFiddle.

    First, you need to take a clipping of the image in your canvas. This is pretty simple. I made another canvas (a hidden one) and used the context.drawImage

    var hidden_ctx = hidden_canvas.getContext('2d');
    
    hidden_ctx.drawImage(
        MainCanvas,
        startClippingX,
        startClippingY,
        clippingWidth,
        clippingHeight,
        pasteX,
        pasteY,
        pasteWidth,
        pasteHeight
    );
    

    Now, we need the Data URL from this canvas so we can download the contents. For this, we will use the canvas.toDataURL method.

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

    Now, all we need to do is make a download link (an a element with an href attribute of our data_url) and we're done!

    0 讨论(0)
  • 2021-01-05 17:44

    Suppose you have a canvas called oldCanvas and you want to save a rectangular area of width w and height h with its upper left corner at x, y.

    Start by making a new canvas element of width w and height h:

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

    Now copy the rectangular area to the new canvas:

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

    Finally, save the new canvas using toDataUrl() or whatever method you were using previously to save a whole canvas.

    For example, you can make an image out of the new canvas:

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

    Then append the new image to the web page:

    document.body.appendChild(newImage);
    

    Or maybe you have a container div that you want to append it to.

    In any case, once the image is in the document, you can right-click on it and save it as usual.

    I've implemented this approach in the following snippet. When you run it, a canvas will be randomly painted. Click and drag on the canvas to select a region that you want to download. A new, downloadable image appears at right.

    // 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';
        };
      };
    };
    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;
    }
    <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>

    0 讨论(0)
提交回复
热议问题