0

I have a requirement to take the canvas from a webpage and convert it to PDF in the backend so it can be saved on the server and downloaded & printed at a later time at 600 DPI.

I have followed this question, and I have a working prototype of the code: AJAX call to send the canvas to backend in Base64 and then a Java function to convert it to PDF.

However, the problem is that the quality of the image is dependent on the screen/browser window size the user has when he clicks the button to trigger the image creation - a fullscreen browser will create a higher-res image than a partial window browser. Example: Both taken on my PC but on the latter the window is about half the screen size. enter image description here enter image description here

I was thinking of somehow creating the canvas on a headless browser with preset size, and that would at least make the quality consistent across users, but I have no idea how to dynamically change the image so I can keep it at 600 DPI no matter the paper size the user chooses to use.

Do I have to draw the canvas shapes directly onto PDF? I know that would fulfill the DPI requirement, but is that even possible to do from an AngularJS/Java stack?

Ariel Lubonja
  • 83
  • 1
  • 10
  • you can set the canvas size **and** use css to change it's display size. I think toDataURL would use the canvas size (not very sure) – apple apple Feb 15 '19 at 13:31
  • So you're saying edit the CSS of the canvas before sending the AJAX request? – Ariel Lubonja Feb 15 '19 at 14:53
  • It sounds like CSS might already be affecting your canvas. If your canvas changes with window size, then it means some proportional sizing is being applied to your canvas, such as a width that is a percentage. Can you show us the CSS rules for your canvas element? – Pop-A-Stash Feb 15 '19 at 15:51

1 Answers1

1

You can decide the proper size for the canvas and then modify the way it's displayed via CSS. Here, the final size is set as 2000x2000 and it will be saved as such (by clicking on it), regardless of the viewport size:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Draw the ellipse
ctx.beginPath();
ctx.lineWidth = 10;
ctx.ellipse(1000, 1000, 500, 800, Math.PI / 4, 0, 2 * Math.PI);
ctx.stroke();

// Draw the ellipse's line of reflection
ctx.beginPath();
ctx.setLineDash([5, 5]);
ctx.moveTo(0, 2000);
ctx.lineTo(2000, 0);
ctx.stroke();


canvas.addEventListener('click', function (e) {
  var dataURL = canvas.toDataURL('image/png');
  var link = document.createElement("a");
  link.download = "finalsize.png";
  link.href = dataURL;
  link.click();
});
<body style="display:flexbox">
 <canvas id="canvas" width="2000" height="2000" style="width:100%; "></canvas>
</body>
Julian
  • 1,277
  • 1
  • 9
  • 20
  • I did something similar, I changed the size using JS, took the image data, then changed the canvas back to the original size. Thanks! – Ariel Lubonja Apr 25 '19 at 11:16