我想给任何能帮助我完全理解这个代码的人提供一张星巴克卡。对我来说很重要。谢谢您抽时间见我!
我开始读洛瓦吉先生的好书(iText in Action,第二版)。它写得很好,内容也很丰富。由于我的雇主压力很大,我不得不跳过第6章。现在,理解new代码示例对我来说是相当重要的,作为一个新程序员,我将尝试用我的问题来评论下面的代码。
如果你可以,当你可以的时候,抽出一些时间,帮我看看下面的问题,那就太好了。我感谢所有有益的评论。
public void manipulatePdf(String src, String dest, int pow)问:在这里,“pow”变量表示,例如,在pow为3的情况下,产生的n-up为(2x2x2) 8,得到的PDF将有8份“src”pdf。这是正确的吗?
答:
throws IOException, DocumentException
{
PdfReader reader = new PdfReader(src);
Rectangle pageSize = reader.getPageSize(1);
Rectangle newSize = (pow % 2) == 0 ?
new Rectangle( pageSize.getWidth(), pageSize.getHeight()) : new Rectangle( pageSize.getHeight(), pageSize.getWidth());问:上面我不知道发生了什么事。在我看来,如果模数运算的其余部分为零,那么新的矩形将在肖像方向上创建,反之亦然。这是正确的吗?若然,我可否问一问原因?
答:
Rectangle unitSize = new Rectangle(pageSize.getWidth(), pageSize.getHeight());
for (int i = 0; i < pow; i++)
{
unitSize = new Rectangle(
unitSize.getHeight() / 2, unitSize.getWidth());
}问:在上面的“for”循环中,我相信,我们正在准备每个pdf的单位大小,这些pdf将被压缩到最终的pdf表面。我不明白为什么getWidth()也不除以2?
答:
int n = (int)Math.pow(2, pow);
int r = (int)Math.pow(2, pow / 2);
int c = n / r;问:“n”是pdfPages的数目,它将被n‘向上加到最终的pdf面。到目前为止还不错对吧?
“r”可以是行数,“c”可以是列数?
So, assuming a 'pow' of 3..
n = 8 which means 8 up of the pdf when you'll open up the final pdf?
r = 2 which means there'll be be two rows.
c = 4 which means there'll be four columns. 答:
Document document = new Document(newSize, 0, 0, 0, 0);
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(String.format(dest, n)));
document.open();
PdfContentByte cb = writer.getDirectContent();
PdfImportedPage page;
Rectangle currentSize;
float offsetX, offsetY, factor;
int total = reader.getNumberOfPages();
for (int i = 0; i < total; )
{
if (i % n == 0)
{
document.newPage();
}问:上面的“for”循环每次在当前工作页中达到预定的nup数时,都会向最终pdf中添加一个新页面。因此,如果我们有n= 8,那么新的页面将在i= 8,16,24,等等调用,对吗?
答:
currentSize = reader.getPageSize(++i);问:这一行的情况下,源pdf有很多页,而不是所有的页面共享相同的pdf页面大小。对,是这样?
答:
factor = Math.min(unitSize.getWidth() / currentSize.getWidth(),
unitSize.getHeight() / currentSize.getHeight());问: min函数返回最小的数。为什么unitSize被currentSize除以?这就是我理解力崩溃的地方。
答:
offsetX = unitSize.getWidth() * ((i % n) % c)
+(unitSize.getWidth()
- (currentSize.getWidth() * factor))/2f;问:好的,offsetX和offsetY用来将pdf页面定位到更大的最终pdf表面。我能理解。有人能用英语向非程序员解释一下计算结果吗?这是一个知道每个数学运算所做的事情,但不了解全局的情况。
答:
offsetY = newSize.getHeight()
- (unitSize.getHeight() * (((i % n) / c) + 1))
+ (unitSize.getHeight()
- (currentSize.getHeight() * factor))/2f;
page = writer.getImportedPage(reader, i);
cb.addTemplate(page,factor, 0, 0, factor, offsetX, offsetY);
}
document.close();
}我希望这个问题能够帮助其他对iText陌生的人,并且可能需要一些详细的代码演练。
我也希望,这种负面的和一般没有帮助的评论将不会被张贴。
谢谢你们的时间和帮助!
发布于 2014-07-27 00:21:01
假设您有一个67页的文档。
如果你想增加这个文档,你将得到34页: 33页,原始文档的2页+1页,只有半页。要在一个相邻的页面上安装两个页面,您需要将原始页面缩小到其大小的一半,并且需要以90度旋转原始页面大小。
如果你想修改这个文档,你将得到17页: 16页,原始文档的4页+1页,即四分之三。要将四个页面放在一个相邻的页面上,您需要将原始页面缩小到原来页面大小的四分之一,而不需要旋转原始页面大小。
如果你想增加8页,你将得到9页:8页,原始文件8页,+1页,只有3/8是满的。要在一页旁边放8页,你需要将原来的页面缩小到1/8,并且你需要将原始页面的大小旋转90度。
如果你想把这个文档放大16页,你将得到5页:4页,原始文档的16页,+1页,只有3/ 16页是满的。要在一页相邻的页面上放满16页,你需要将原来的页面缩小到1/16,并且你不需要旋转原来的页面大小。
如果你想把这个文档增加32页,你将得到3页:2页,原始文档的32页,+1页,只有3/32页是满的。要在一个相邻的页面上容纳32页,您需要将原始页面缩小到其大小的1/32,并且需要以90度旋转原始页面大小。
如果您想要将此文档提高到64页,您将得到2页:1页,原始文档的64页,+1页,仅为3/64页。要在彼此相邻的一页上容纳64页,您需要将原始页面缩小到1/64大小,并且不需要旋转原始页面大小。
2=2 (pow 1) =>旋转页
4=2x2 (pow 2) =>不旋转页面
8=2x2x2 (pow 3) =>旋转页
16 =2x2(POW4) =>不旋转页面
32 =2x2 (pow 5) =>旋转页
64 =2x2(POW6) =>不旋转页面
你看到模式了吗?当pow是奇数时,需要旋转页面;当它是偶数时,不需要旋转页面。这就是为什么您需要测试(pow % 2) == 0。它定义了新页面的方向。
这个循环也很容易理解,特别是当您查看这个图像时:

大页面A0可以分为两个A1页面。此A1页的高度是A0页的宽度;A1页的宽度是A0页高度的一半。A1可以分为两个A2页面。此A2页的高度是A1页的宽度;A2页的宽度是A1页高度的一半。诸若此类。
您是对的,n是我们将尝试安装在一个页面上的页面数,r是行数,c是列数以及接下来的内容。
现在我们需要定义factor。您已经知道width和height被切换了几次。例如:当使用A4页面2次增加文档时,原始页面大小为210x297,需要将其更改为unitSize 148乘以210。换句话说,它需要缩小到系数148 / 210 (0.705)或210 / 297 (0.707)。在这种情况下,我们使用因子0.705。
我们可以像这样计算偏移量:
offsetX = unitSize.getWidth() * ((i % n) % c);
offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c);如果您想对文档进行8次升级,c等于4。
(0 % 8) % 4 = 0 % 4 = 0; (0 % 8) / 4 = 0 / 4 = 0;
(1 % 8) % 4 = 1 % 4 = 1; (1 % 8) / 4 = 1 / 4 = 0;
(2 % 8) % 4 = 2 % 4 = 2; (2 % 8) / 4 = 2 / 4 = 0;
(3 % 8) % 4 = 3 % 4 = 3; (3 % 8) / 4 = 3 / 4 = 0;
(4 % 8) % 4 = 4 % 4 = 0; (4 % 8) / 4 = 4 / 4 = 1;
(5 % 8) % 4 = 5 % 4 = 1; (5 % 8) / 4 = 5 / 4 = 1;
(6 % 8) % 4 = 6 % 4 = 2; (6 % 8) / 4 = 6 / 4 = 1;
(7 % 8) % 4 = 7 % 4 = 3; (7 % 8) / 4 = 7 / 4 = 1;
(8 % 8) % 4 = 0 % 4 = 0; (8 % 8) / 4 = 0 / 4 = 0;
(9 % 8) % 4 = 1 % 4 = 1; (9 % 8) / 4 = 1 / 4 = 0;你看到模式了吗?我们在网格中添加如下页面:(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1)。为了得到真实的维数,我们用unitSize.getWidth()和unitSize.getHeight()进行乘法。很明显,我们需要
offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c);由于坐标系的性质:坐标系的起源在左下角。
我们调整offsetX和offsetY的一半的实际宽度差异的大小,向下页和可用的空间,以中心导入的页面。
你说你不想听到任何负面的评论。请允许我说一句:你的问题是,不是iText问题,也不是编程问题。这是一个数学问题。你真的需要在尝试编程之前学习数学,就像孩子在学会跑步之前需要学会走路一样。
造成混淆的一个可能原因可能是您没有考虑到ISO 216的一个特殊特性。该算法不适用于非标准页面。例如:如果您的页面是正方形,则不能将高度分为两部分并保持宽度。但这很明显,不是吗?
https://stackoverflow.com/questions/24974703
复制相似问题