Printing HTML5 Canvas in the correct size

2020-05-28 17:47发布

问题:

Is there a correct way to specify the size of a canvas element in for example millimeters so that if I print it out it will have the correct size?

I've tried this simple example:

<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas"
style="border:1px solid #c3c3c3; width:50mm; height:50mm;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0,0,150,75);
</script>
</body>
</html>

But on screen the canvas is 45mm instead of 50mm and when printed its 55mm ^^

回答1:

Part 1: How many canvas pixels are required to generate a 50mm printed drawing?

Printers typically print at 300 pixels per inch.

In millimeters: 300ppi / 25.4 mm-in = 11.81 pixels per millimeter.

So if you want to print a 50mm drawing you would calculate the required pixel size like this:

50mm x 11.81ppm = 590.5 pixels (591 pixels)

And you resize the canvas to have 591 pixels (assuming square) like this:

// resize the canvas to have enough pixels to print 50mm drawing
c.width=591;
c.height=591;

Part 2: Exporting the canvas as an image

To print the canvas, you will need to convert the canvas into an image which you can do with context.toDataURL.

// create an image from the canvas
var img50mm=new Image();
img50mm.src=canvas.toDataURL();

Part 3: Convert the exported image to proper print resolution

context.toDataURL always creates an image that is 72 pixels per inch.

Printers typically print at higher resolution, maybe 300 pixels per inch.

So for the exported image to print properly on the page, the exported image must be converted from 72ppi to 300ppi.

The ImageMagick library can do the conversion: http://www.imagemagick.org/

It's a server side tool so you will have to bounce the exported image off your server (probably using AJAX to round-trip your image).

ImageMagick works in PHP, IIS and other server environments.

Here's an example which use PHP to convert the image resolution and echo the converted image back to the caller:

// Assume you've uploaded the exported image to
// "uploadedImage.png" on the server
<?php
  $magic = new Imagick();
  $magic->setImageUnits(imagick::RESOLUTION_PIXELSPERINCH);
  $im->setImageResolution(300,300);
  $im->readImage("uploadedImage.png");
  $im->setImageFormat("png");
  header("Content-Type: image/png");
  echo $im;
?>

Final Part: Print it!

The converted file you receive back from the server will print a 50mm square image on your 300ppi printer.



回答2:

Don't use style to declare the width and height. Declare it in pixels in the element, like this: <canvas width = "500" height = "500"></canvas>

Should work.



回答3:

If you had decided to process generated PNG at the server side, you can set PNG pHYs chunk in pure PHP.



标签: html canvas size