【问题标题】:How to draw an image in real size and ensure printing will be correct如何绘制真实尺寸的图像并确保打印正确
【发布时间】:2017-02-03 11:22:59
【问题描述】:

我真的不知道如何将我的问题转化为一个问题,但这里有一个很好的描述:

假设我想在 HTML 画布上绘制一个正方形,尺寸为 1" x 1"。 我知道使用像素作为可打印长度是没有意义的,我们需要考虑 DPI。在以下示例中,我采用了 300 的 dpi:

<canvas id="myCanvas" width="400" height="400"></canvas>

这是我的 Javascript:

var dpi = 300;
var cContext = document.getElementById("myCanvas").getContext("2d");

cContext.moveTo(50,  50);

// Draw a square
cContext.lineTo(350, 50);
cContext.lineTo(350, 350);
cContext.lineTo(50,  350);
cContext.lineTo(50,  50)

cContext.stroke();

The result is a nice square with width 300px in a 300dpi setting,所以在纸上打印时应该打印一英寸见方。但问题是它没有。我检查了打印机设置并使用了 300dpi。

谁能告诉我我做错了什么,或者指出我正确的方向?

【问题讨论】:

  • 那么,打印出来的尺寸是多少?
  • 一条 7.6cm 的线以 100dpi 渲染并以 100dpi 打印出来为 7.4cm。同样的故事,一行 15.2 厘米,打印 14.7 厘米。
  • A good reading ? 根据MDN,画布始终以 96dpi 输出,这似乎与您的差异有关。 (即使我测试它,我有 72dpi 的文件..)

标签: javascript canvas printing dpi


【解决方案1】:

打印质量/DPI

打印机的DPI设置与源图像DPI无关,俗称打印质量。

您需要打印尺寸

图像 DPI 取决于其分辨率(以像素为单位的宽度和高度)和以毫米或英寸为单位打印的尺寸,以提供打印分辨率(iDPU“每单位图像点数”,供本答案进一步参考)。

除非您还将固定的打印尺寸与图像相关联,否则图像 DPI 是没有意义的。

如果打印机的 DPI 设置与图像的 iDPI 不同,则打印机(或驱动程序)将对图像 DPI 进行下采样或上采样以匹配所需的 DPI。您要避免下采样,因为这会降低图像质量。

页面大小

让打印机 DPI 与图像 iDPU 匹配。此示例适用于纵向模式的 A4 页面。您可以使用任何尺寸的打印页面,但您需要知道实际的物理尺寸。

const pageSizes = {
   a4 : {
      portrait : {
          inch : {
             width : 8.27,
             height : 11.69,
          },
          mm : {
             width : 210,
             height : 297,
          }
      },
      landscape : {
          inch : {
             height : 8.27,
             width : 11.69,
          },
          mm : {
             width : 297,
             height : 210,
          }
      },
}

画布分辨率

创建一个 iDPI 300 为 2 x 2 英寸的画布。

const DPI = 300;  // need to have a selected dots per unit in this case inches
const units = "inch";
const pageLayout = "portrait";
const printOn = "a4";
// incase you are using mm you need to convert
const sizeWidth = 2;  // canvas intended print size in units = "inch"
const sizeHeight = 2;
var canvas = document.createElement("canvas");
canvas.width = DPI * sizeWidth;
canvas.height = DPI * sizeHeight;

画布尺寸

缩放画布以适应页面大小,以匹配打印尺寸。这将是画布打印尺寸/页面打印宽度

canvas.style.width = ((sizeWidth / pageSizes[printOn][pageLayout][units].width) * 100) + "%";

对于高度,您需要假设像素方面是正方形,并且页面的高度可能比打印页面长或短,因此您必须使用像素。

canvas.style.height = Math.round((sizeHeight / pageSizes[printOn][pageLayout][units].width) * innerWidth) + "px";

将画布添加到页面

document.body.appendChild(canvas);
  • 注意:画布必须添加到页面主体或页面宽度 100% 的元素。 IE 以像素为单位的宽度 === innerWidth。

  • 注意:画布不应有边框、内边距、边距或继承任何影响其大小的 CSS 样式。

打印

  • 确保打印机质量设置为 300DPI(或更高)。
  • 选择页面尺寸(在本例中 A4 为 210 × 297 毫米或 8.27 × 11.69 英寸)
  • 选择要纵向的布局。
  • 在打印选项中选择无边框。
  • 打印

带边框打印。

如果您想要打印页面上的边框,您需要使用自定义边框,以便您知道边框大小。 (注意示例仅使用英寸)

 const border = { // in inches
     top : 0.4,
     bottom : 0.4,
     left : 0.4,
     right : 0.4,
 }
    

如上所示创建画布。

画布大小

canvas.style.width = ((sizeWidth / (pageSizes.a4.portrait.width - border.left - border.right) * 100) + "%";

高度变得有点复杂,因为它需要为边框调整页面的像素宽度。

canvas.style.height = Math.round((sizeHeight / (pageSizes.a4.portrait.width  - border.left - border.right)) * innerWidth * (1 - (border.left - border.right) / pageSizes.a4.portrait.width)  ) + "px";

【讨论】:

  • 将画布缩放到完全是 A4 对我来说是诀窍,因为更大的画布必须缩小以适应 A4。最后,我还从画布的宽度和高度中减去了大约 15 毫米,以说明打印机无法在没有边距的情况下打印。
【解决方案2】:

我注意到您以厘米而不是英寸为单位测量的 cmets(不错的选择,公制 FTW),所以这里有一个正确处理这些度量的注释示例

var dpi = 300; // the print resolution
var ppmm = dpi / 25.4; // get the pixel-per-millimeter ratio

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var x = 5 * ppmm; // 5mm
var y = 5 * ppmm; // 5mm
var w = 76 * ppmm; // 76mm
var h = 76 * ppmm // 76mm

ctx.rect(x, y, w, h); // drawing a rectangle the simple way
ctx.stroke();

var data = canvas.toDataURL(); // extract the image data

// inject the image data into a link, creating a downloadable file
var link = document.getElementById("link");
link.setAttribute('href', 'data:application/octet-stream;charset=utf-16le;' + data);
link.setAttribute('download', "image.png");
<!-- the canvas is scaled down from 300dpi to 96dpi it shouldn't affect the final image but it makes it nicer for the screen and more manageable -->
<canvas id="canvas" width="1125px" height="1125px" style="width:360px;height:360px"></canvas>
<a href="#" id="link">download</a>

要打印 7.5 厘米的 300dpi 图像,您必须获得每毫米像素的比率并将您的尺寸乘以该比率。

当您下载图像时,它将是 1125x1125 像素的 72dpi 图像,将其重新采样为 300dpi,您将获得 270x270 像素,打印时等于 95.25 毫米(对于整个图像、填充和所有)。

绘制的矩形边长为 897.6377952755906px,在 300dpi 时打印输出为 76mm

顺便说一句,小数像素大小是我缩小屏幕上画布的原因。由于我们优先考虑打印,因此屏幕图像会受到影响并且看起来很模糊,将其缩小会使它看起来更清晰。此外,它的尺寸更易于在浏览器中查看。

最后一点:显然视网膜屏幕使用不同的 dpi 值来渲染画布,因此矩形看起来会更小。在“正常”分辨率的显示器上,它的屏幕尺寸也为 7.6 厘米。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多