2

I am trying to download the canvas as image. My canvas height is 500px and width is also 500px but i want to download the image with 700px without change into the canvas size.

My code is as below :

    <div class="surface">
     <canvas id="myCanvas" height="500" width="500"></canvas>
    </div>

<a id="downloadImgLink" onclick="$('#downloadImgLink').attr('href', myCanvas.toDataURL());" download="MyImage.png" href="#" target="_blank" class="btn btn-danger">Download</a>

Above code is download the image with 500px height and width, but i need the image with 700px or any custom size without changes the canvas size.

Is there any possible way to download any canvas as image with custom size, without canvas resize?

dvs.spy
  • 65
  • 2
  • 12
  • 1
    There is a version of `drawimage` that will simultaneously scale and draw your image. For example, this will take your 500x500 imageObject (`img`) and resize it to 700x700 before drawing it onto the canvas: `drawImage(img,0,0,500,500,0,0,700,700)` – markE Oct 09 '15 at 14:29

3 Answers3

5

There is no size parameter on any of the built-in export methods for the canvas element (toDataURL() and toBlob()).
However, you can write your own implementation quite easily :

As markE mentioned in comments, ctx.drawImage( ) has an option to resize the drawn image ctx.drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight, destinationX, destinationY, destinationWidth, destinationHeight);.
Also you can pass a canvas element as its first image parameter.

Then you could write something like :

canvas.resizeAndExport = function(width, height){
  // create a new canvas
  var c = document.createElement('canvas');
  // set its width&height to the required ones
  c.width = width;
  c.height = height;
  // draw our canvas to the new one
  c.getContext('2d').drawImage(this, 0,0,this.width, this.height, 0,0,width, height);
  // return the resized canvas dataURL
  return c.toDataURL();
  }

// draw a simple rectangle for the example
canvas.getContext('2d').fillRect(0,0,50,200);
// create an image that will get our resized export as src
var img = new Image();
img.src = canvas.resizeAndExport(40, 40);
document.body.appendChild(img);
img, canvas{border: 1px solid}
<canvas height="200" width="200" id="canvas"></canvas>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0

In general you have to create another canvas with the custom size, reapply all the drawing instructions you run for the main one, and then call toDataURL().

function draw(context){
  // wrap your drawing instructions in a function
  // it will accept a canvas context as input and will draw on it
  // this can be reused for the main and the custom canvas
}

function downloadCanvas(width, height){
  var canvas = document.createElement('canvas');
  var context = canvas.getContext('2d');
  canvas.width = width;
  canvas.height = height;
  // re-apply all the drawing instructions to this context
  draw(context);

  // now export the data from this canvas
  return canvas.toDataURL();
}
MarcoL
  • 9,829
  • 3
  • 37
  • 50
  • Is it possible without `callback` ? – Rayon Oct 09 '15 at 08:35
  • Is there any methods to passing parameter of height and width to canvas and download using toDataUrl() ? – dvs.spy Oct 09 '15 at 08:40
  • @RayonDabre which callback? dvs.spy there's no native method, unless you want to scale/resize the main canvas, but if the custom size is bigger than the native one you're stretching the image (with bad results often ). – MarcoL Oct 09 '15 at 09:07
  • @dvs.spy, Just feel that canvas re-draw wont be synchronous operation. – Rayon Oct 09 '15 at 09:16
  • The drawing is synchronous: http://jsfiddle.net/o5ja5rko/ (or https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API for ref ). In case of animation you may want to have a callback, but this is not the case. – MarcoL Oct 09 '15 at 11:53
  • So if your canvas is updated by user interaction or randomness, you will keep track of every of these variables??? – Kaiido Oct 13 '15 at 03:16
  • Yes, this is the common strategy. – MarcoL Oct 13 '15 at 06:28
  • Usually the canvas has an associated state to keep track of what to draw. On exporting time all the instructions are re-executed following that state. – MarcoL Oct 13 '15 at 06:55
  • He doesn't want to resize the canvas, which is what 'drawImage' does. The alternative is to redraw the canvas. That's it. – MarcoL Oct 13 '15 at 07:31
  • Exactly but then use drawImage instead of recalling all drawing methods... (Even if you want to resize the canvas you should draw it on an off page one first then redraw back on the visible one) – Kaiido Oct 13 '15 at 15:41
-1

You can make use of the getImageData() method to get the ImageData object with particular width and height. Even more you can specify the starting point (x and y) for it.

Once you get the ImageData object, create a in-memory canvas object with width and height same as the ImageData object and use putImageData() method to draw it to the canvas. Then use toDataURL() method to get the dataUrl of the canvas.

Sample:

var imgData = ctx.getImageData(x, y, width, height);

var tc = document.createElement('canvas');
tc.width = imgData.width;
tc.height = imgData.height;
var tctx = tc.getContext('2d');
tctx.putImageData(imgData, 0, 0);
console.log(tc.toDataURL('image/png'));

Here is the fiddle: http://jsfiddle.net/k7moorthi/eb51c088/

CREDITS:

downloadURI - owencm

Community
  • 1
  • 1
Kesavamoorthi
  • 959
  • 2
  • 11
  • 21