Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to crop canvas.toDataURL

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

like image 904
doge45 Avatar asked Dec 14 '22 10:12

doge45


2 Answers

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>
like image 77
markE Avatar answered Dec 17 '22 01:12

markE


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>
like image 40
Carson Avatar answered Dec 17 '22 02:12

Carson