我正在使用 Flying Saucer 进行HTML到PDF的转换。我需要以 Letter 大小生成600dpi的输出PDF。我怎样才能做到这一点?
答案 0 :(得分:12)
有四种不同的因素在起作用,它们都是相互关联的:
你希望页面指标是正确的,这样当你要求飞碟制作一个"字母"大小页面,生成的PDF将在Acrobat中显示为测量8.5和#34; x 11"。您可以通过在CSS中指定page-size属性直接在FS中配置页面大小,如另一个答案中所述:@page { size: letter; }
您希望最终输出适合在某个XXX dpi的某些打印机上打印。这一切都很好,但请记住,PDF(大多数情况下)是一种矢量格式。我没有检查规格,但据我所知,PDF文件/页面没有"#34;分辨率,因为它们是基于矢量的。话虽如此,页面内的内容具有有效的分辨率,因此我们需要您想要的XXX dpi数来计算下面的数字。
在FlyingSaucer(和Java)世界中,一个点总是恒定的1/72英寸。期。因此,我们可以通过获取所需的分辨率并除以点的大小来计算每点的点数值。例如,如果您想要 300 dpi输出:
这不是幻数,此值与每点数的数字以及您尝试输入FlyingSaucer的图形图像的预期分辨率直接相关。更具体地说,给定尺寸为X x Y像素的图形图像,您需要确定要在PDF中呈现的大小。如果您使用的是为屏幕(网络)使用而准备的图像,则可能是标准的96像素/英寸(因此96 x 96像素图像将在PDF输出上呈现为1英寸的正方形)。
因此我们可以轻松地计算每像素点数,如下所示,再次假设我们想要300 dpi输出:
如果采用这种方法,您的图像尺寸将正确,但它们不会成为您正在寻找的300 dpi打印质量。那是因为你的图像开始时的分辨率不够高。更多关于这一点。
如果您只是按照其中一个答案中的建议直接致电SharedContext#setDPI
,那么您可能会得到错误的结果。这是因为在不改变分辨率(每英寸点数)的情况下改变每点数也没有逻辑意义。 ITextRenderer构造函数对setDPI(72*dotsPerPoint)
进行固定调用,当它创建新页面时,它还使用构造函数设置的dotsPerPoint值来计算正确的页面宽度(以磅为单位)。如果您通过调用setDPI
更改了其下方的分辨率,则最终会出现错误的页面大小。
正确的方法是使用我们上面计算的值创建一个新的ITextRenderer对象。如果我们想要300 dpi输出并且我们有96 ppi图像来提供它,我们会打电话:
ITextRenderer renderer = new ITextRenderer(4.1666f, 3);
请注意,每像素点参数只接受整数,因此我们将3.125舍入到上面最接近的整数。然而......它确实是两个数字之间的比例似乎很重要,所以为了使最后一个参数成为整数,我们可以将这两个数乘以8(产生整数的最小整数乘数),给出33.3333和确切的25.这也是我对魔法起源的猜测" 20"飞碟来源中的数字。
到目前为止,您的输出PDF应该与您开始时的输出相同(假设您之前使用的是飞碟的默认96 ppi配置)。但现在我们知道需要调整的参数以使一切正常。
因此我们已经验证上述参数适用于我们的目的,但我们的图像仍然低至96 ppi。如果我们想以高分辨率打印这些东西,你需要做的就是换掉300 ppi版本的图像,更改构造函数参数,然后你就完成了,对吧?
也许。让我们来看看数字:
您的预期输出分辨率(300 dpi)不会改变,因此每点的点数仍为4.1666。但您的输入图像现在为300 ppi,因此您的每像素点数= 300点/英寸/ 300像素/英寸= 1点/像素。所以你现在就像这样调用构造函数:
ITextRenderer renderer = new ITextRenderer(4.1666f, 1);
执行此操作后,您的新300 px x 300 px图像将最终为1" PDF上的正方形,这正是您想要的打印质量。
飞碟使用每像素点数测量来转换许多东西,而不仅仅是图像。特别是,如果您在样式表中指定了使用像素的任何内容,则每像素点数的测量也会对其大小产生影响。
如果您有像font-size: 10px;
这样的样式表规则,那么增加提供给构造函数的每像素点将使该文本变小,这可能也不是您想要的。毕竟,您应该能够提高PDF中图像的分辨率,同时保持文本的大小和位置相同。
答案是将样式表中的所有内容转换为使用点。 (或英寸。至少像素以外的东西!)如果你开始使用默认的飞碟设置(意味着像素是96 ppi),你只需要转换所有的" px"测量成点。由于72点= 1英寸,你会改变" px"到" pt"并将该值乘以72/96。
例如,上面的font-size: 10px;
将变为font-size: 7.5pt;
。如果你想要与之前的内容保持真正的一致性,那么CSS中的所有内容都会提及" px" (以及任何内联样式)必须更改为" pt"也有相同的转换。
完成此更改后,文本和其他布局将保持一致,如果您决定稍后需要600 dpi输出,则可以调整图像并更改构造函数参数,但其余布局将仍然保持不变。完成!
答案 1 :(得分:3)
您可以在HTML文档中使用CSS page size属性设置字母大小:
@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
给出。
答案 2 :(得分:2)
使用Flying Saucer时设置DPI的简单答案:
renderer.getSharedContext().setDPI(600);
与obourgain的回答一样,与@page { size:letter; }
CSS结合使用。