我正在使用Flying Saucer进行HTML转PDF。我需要生成一个600dpi的输出PDF,大小为Letter。我该如何实现这一点?
我正在使用Flying Saucer进行HTML转PDF。我需要生成一个600dpi的输出PDF,大小为Letter。我该如何实现这一点?
有四个不同的因素在起作用,它们之间相互关联:
您希望页面度量正确,这样当您要求 Flying Saucer 生成“信纸”大小的页面时,所得到的 PDF 将在 Acrobat 中显示为 8.5" x 11"。您可以通过在 CSS 中指定 page-size 属性直接配置 FS 页面大小,如 obourgain 在另一个答案中所提到的:@page { size: letter; }
您希望最终输出适合在某个打印机上打印出 XXX dpi。这很好,但请记住,PDF(大多数情况下)是矢量格式。我没有检查过规范,但据我所知,PDF 文件/页面没有分辨率,因为它们是基于矢量的。话虽如此,在页面中放置的东西具有有效的分辨率,所以我们需要您所需的 XXX dpi 数字来计算下面的数字。
在 FlyingSaucer(和 Java)世界中,一点始终是英寸的恒定值 1/72。所以我们可以通过取所需分辨率并除以点的大小来计算每点的点数值。例如,如果您想要300 dpi 输出:
这不是一个魔法数字,这个值与每点点数以及您试图输入 FlyingSaucer 的图形图像的预期分辨率直接相关。更具体地说,考虑到一个 X x Y 像素维度的图像,您需要决定要在 PDF 中呈现多大。 如果您正在使用为屏幕(Web)使用准备的图像,则可能从标准的 96 像素/英寸开始(因此,96 x 96 像素的图像将呈现为 PDF 输出上的一英寸正方形)。
因此,我们可以轻松计算出每像素点数,假设我们想要 300 dpi 输出:
如果您采用这种方法,那么您的图像大小将是正确的,但它们不会具有您所寻找的 300 dpi 打印质量。这是因为您的图像分辨率不够高。稍后我们将详细介绍这一点。
如果您只是像另一个答案建议的那样直接调用 SharedContext#setDPI,则可能会得到错误的结果。这是因为更改每点点数而不更改分辨率(每英寸点数)毫无逻辑意义。ITextRenderer 构造函数以固定值调用 setDPI(72*dotsPerPoint) ,并在创建新页面时,还使用构造函数设置的 dotsPerPoint 值计算正确的页面宽度(以点为单位)。如果您在其鼻子下更改了分
ITextRenderer renderer = new ITextRenderer(4.1666f, 3);
请注意,每像素点数参数只接受整数,因此我们将3.125四舍五入到最接近的整数。但是...两个数字之间的比率似乎很重要,所以为了使最后一个参数成为整数,我们可以将两个数字都乘以8(产生整数的最低整数倍数),这将给出33.3333和25。这也是我对飞碟源代码中神奇的“20”数字起源的猜测。
ITextRenderer renderer = new ITextRenderer(4.1666f, 1);
一旦你这样做了,你的新300像素 x 300像素的图像将以1英寸的正方形出现在PDF上,这正是你想要的打印质量。
Flying Saucer使用每像素点数(dots-per-pixel)来转换许多东西,不仅仅是图片。特别是,如果你已经在样式表中指定了任何使用像素的东西,那么每像素点数对它们的大小也会有影响。
如果你有像 font-size: 10px;
这样的样式表规则,那么增加提供给构造函数的每像素点数将使该文本更小,这可能也不是你想要的。毕竟,你应该能够在保持文本大小和位置不变的情况下增加PDF中图像的分辨率。
答案是将样式表中的所有内容都转换为使用磅(points)。(或英寸。至少不要使用像素!)如果你从默认的Flying Saucer设置开始(意味着像素为96 ppi),你只需要将所有"px"测量值转换为磅。由于72点=1英寸,你需要将"px"改为"pt"并将值乘以72/96。
例如,上面的 font-size: 10px;
将变为 font-size: 7.5pt;
。如果你想要与之前的真正一致性,那么CSS中提到"px"的所有内容(以及任何内联样式)也必须进行相同的转换,改为使用"pt"。
一旦你进行了这个更改,你的文本和其他布局就会保持一致,如果你决定稍后需要600 dpi的输出,你只需调整图像并更改构造函数参数,但其他布局仍将保持不变。完成!
renderer.getSharedContext().setDPI(600);
@page { size:letter; }
CSS一起使用。@page { width:5in; height:4in }
。 - Charles Goodwin @page {
size: letter;
}
ITextRenderer
构造函数更改文档的dpi:public ITextRenderer(float dotsPerPoint, int dotsPerPixel)
我不太明白这些值到底代表着什么,但默认值为dotsPerPoint = 20f * 4f / 3f
和 dotsPerPixel = 20
,输出的是96dpi的文档。
要得到600dpi,可以使用 dotsPerPoint = 500f / 3f
和 dotsPerPixel = 20
。
查看ITextRenderer的代码,最终的dpi由以下公式给出:dpi = dotsPerPoint * 72 / dotsPerPixel
。
margin-top: 0.5pt; height: 0.5pt;
。 - Scott Dudley