7

Hello,
I want to crop my canvas.toDataURL() before sending it on the server, but I didn't find how :(
Here's my code :

TakePhoto: function() {
        var myCanvas = document.getElementById('game');
        var dataURL = myCanvas.toDataURL();
        // crop the dataURL
    }

So, how to crop the dataURL ?
Can anyone help me ?
Thanks in advance

doge45
  • 83
  • 1
  • 4

2 Answers2

12

The toDataURL method will always capture the whole canvas.

So to capture a cropped portion you will have to create a temporary canvas and size it to the same size as the crop.

Then use the extended form of drawImage to both crop the original image and draw it onto the temporary canvas.

enter image description here

Example code and a Demo:

var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src="https://i.stack.imgur.com/EUBBt.png";
function start(){
  var croppedURL=cropPlusExport(img,190,127,93,125);
  var cropImg=new Image();
  cropImg.src=croppedURL;
  document.body.appendChild(cropImg);
}

function cropPlusExport(img,cropX,cropY,cropWidth,cropHeight){
  // create a temporary canvas sized to the cropped size
  var canvas1=document.createElement('canvas');
  var ctx1=canvas1.getContext('2d');
  canvas1.width=cropWidth;
  canvas1.height=cropHeight;
  // use the extended from of drawImage to draw the
  // cropped area to the temp canvas
  ctx1.drawImage(img,cropX,cropY,cropWidth,cropHeight,0,0,cropWidth,cropHeight);
  // return the .toDataURL of the temp canvas
  return(canvas1.toDataURL());
}
body{ background-color: ivory; }
img{border:1px solid red; margin:0 auto; }
<h4>Original image</h4>
<img src='https://i.stack.imgur.com/EUBBt.png'>
<h4>Cropped image create from cropping .toDataURL</h4>
tao
  • 82,996
  • 16
  • 114
  • 150
markE
  • 102,905
  • 11
  • 164
  • 176
  • Thanks! Note to self: when populating the image using data-url (instead of loading from a url) you still need to use the onload handler because it doesn't draw the image to the canvas synchronously, as per https://stackoverflow.com/questions/4773966/drawing-an-image-from-a-data-url-to-a-canvas – pythonjsgeo May 23 '17 at 01:24
1

This is another example.

Assuming you already have a canvas and want to do some modifications.

for example, you may use html2canvas.js, which will return a canvas for you, but you may want to edit it...

But as an example, I don't want to involve too many unrelated packages, so in my example, I use a simple method to generate a canvas

Example

<img id="original">
<br>
<button>click me</button>
<br>

<script>
  window.onload = () => {
    // Create a canvas to represent a canvas generated by your programs.
    const img = document.querySelector(`#original`)
    const orgCanvas = document.createElement(`canvas`)
    const orgCanvasCtx = orgCanvas.getContext(`2d`)
    img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAA1JJREFUaEPtmlmoTVEYx3/nTRkiUaYHSoREhgwpU3gwhjdPXkik3IQkbombBykPhjwoeaHMmQsvIkOIMpYnmZIhTxL9b9+qbd+99j777rOds0971e109lrrW9//+/+/b629zq1Q8FYpuP80FYCzwHigf4Oz8g64DyySn46BPw3utM+9igDsBjYXFECbADwHhhUUwAsBKKp82mNeAqi39EoGSgYyRqCUUMYAZp6eloHPwC5gCTAt8+o1MJAWwFjgA/AS6Bax/ozQM40ZaUeVnjXwt4OJNABuAnJwB7Dd44zveD4GOAcMqjWIagDorDQEuA18AiYA34HREc7I3nTghvWdBx4a6LXA/v8JQFJZDNyxRWcCj4Av9l2OHgMGBpwKA1DXM2CUHRgVDLUnATv6LltqYlltHNA9YNc9HwAMDQYhjoGlwKmYiI0ATpjG3bAoAOqT9OSEDo4ngXWWS26ek6U+W4HrwCzr/GGABgNXwv74AHwFeiXQfdoYCgckKCH1icHJxoBk2NsmHAC6AAeBu8BlQIk+ySrdFht3FZgLtAGbqgXgEjYOwzegR2hAmIF9wC3gDKAcWGGOaporBMft+R5gIzDRZOnY3wlsA+7ZK+8/S/oYqAbA05B8ZDhNFdIar4GPwNZAdZOMjhgr0vxCk5tY6tB8AFRt+iZIaB5wycOAexy1D7SYxpXIWkN/CobLAzkqGYkBSU8leKXJqmoAGijdSX9xLax3XxI7Gw9MBnJ2viVn1P6iV1wVESXybOCafaYCcAhYnQBAVzGi2LUkAKowcl6b2gKbJEb2hjZIJavAKkBHgVc+ecaVUcloiuk0CsdyK6NJVSjY7xiYCqwHLgI/rbQGd3hVrjnGkNhQpYpsSTuxNL7GFpHmVZNVUfpY8oWNJjGg8RsAleC3pnVd60QdUfoB7w3css4CcPMUpa72RXtE1oPZL+ANMDxGotq4fgOP4/akJAYSUiC37sPAKjs7af/wtkYEENxLEu+sGhGAKpWakjxRqo0IIJUuSwCpwpXD4JKBHIKaymTJQKpw5TC4KRgo/E9McRdVOZBeU5Ot7tyhiyh3N1PTFXI01v4mFzw4BV/zclw3s2m9FF2wN7jm+leDzKGphwHfPU49fOnUmn8Bhg+5xswBadMAAAAASUVORK5CYII="
    img.onload = e => {
      orgCanvasCtx.drawImage(e.target, 0, 0)
    }

    document.querySelector(`button`).onclick = () => {
      // Getting start crop after orgCanvas is ready.
      const quality = 1.0
      const blobURL = orgCanvas.toDataURL(`image/png`, quality)
      const cropImg = new Image()
      cropImg.src = blobURL
      cropImg.dataset.cropOptions = JSON.stringify({  // like <img data-crop-options="...">
        x: 3, y: 10, width: 15, height: 26
      })
      cropImg.onload = () => {
        URL.revokeObjectURL(cropImg.src)
        if (cropImg.dataset.cropOptions === "") {
          return
        }
        const {x, y, width, height} = JSON.parse(cropImg.dataset.cropOptions)
        const cropCanvas = document.createElement(`canvas`);
        [cropCanvas.width, cropCanvas.height] = [width, height]

        const cropCanvasCtx = cropCanvas.getContext(`2d`)
        cropCanvasCtx.drawImage(cropImg,
          x, y, width, height,
          0, 0, width, height, // paste it to the left upper corner
        )

        cropImg.dataset.cropOptions = "" // stop callback
        cropImg.src = cropCanvas.toDataURL(`image/png`, quality) // it will do cropImg.onload again ...
      }
      document.body.append(cropImg)
    }
  }
</script>
Carson
  • 6,105
  • 2
  • 37
  • 45