首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java -> iText -> Imposition (n-Up) ->示例

Java -> iText -> Imposition (n-Up) ->示例
EN

Stack Overflow用户
提问于 2014-07-26 19:21:40
回答 1查看 794关注 0票数 0

我想给任何能帮助我完全理解这个代码的人提供一张星巴克卡。对我来说很重要。谢谢您抽时间见我!

我开始读洛瓦吉先生的好书(iText in Action,第二版)。它写得很好,内容也很丰富。由于我的雇主压力很大,我不得不跳过第6章。现在,理解new代码示例对我来说是相当重要的,作为一个新程序员,我将尝试用我的问题来评论下面的代码。

如果你可以,当你可以的时候,抽出一些时间,帮我看看下面的问题,那就太好了。我感谢所有有益的评论。

代码语言:javascript
复制
public void manipulatePdf(String src, String dest, int pow)

问:在这里,“pow”变量表示,例如,在pow为3的情况下,产生的n-up为(2x2x2) 8,得到的PDF将有8份“src”pdf。这是正确的吗?

答:

代码语言:javascript
复制
 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());

问:上面我不知道发生了什么事。在我看来,如果模数运算的其余部分为零,那么新的矩形将在肖像方向上创建,反之亦然。这是正确的吗?若然,我可否问一问原因?

答:

代码语言:javascript
复制
  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?

答:

代码语言:javascript
复制
  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”可以是列数?

代码语言:javascript
复制
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. 

答:

代码语言:javascript
复制
  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,等等调用,对吗?

答:

代码语言:javascript
复制
    currentSize = reader.getPageSize(++i);

问:这一行的情况下,源pdf有很多页,而不是所有的页面共享相同的pdf页面大小。对,是这样?

答:

代码语言:javascript
复制
    factor = Math.min(unitSize.getWidth() / currentSize.getWidth(),
                      unitSize.getHeight() / currentSize.getHeight());

问: min函数返回最小的数。为什么unitSize被currentSize除以?这就是我理解力崩溃的地方。

答:

代码语言:javascript
复制
    offsetX = unitSize.getWidth() * ((i % n) % c)
              +(unitSize.getWidth()
              - (currentSize.getWidth() * factor))/2f;

问:好的,offsetX和offsetY用来将pdf页面定位到更大的最终pdf表面。我能理解。有人能用英语向非程序员解释一下计算结果吗?这是一个知道每个数学运算所做的事情,但不了解全局的情况。

答:

代码语言:javascript
复制
    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陌生的人,并且可能需要一些详细的代码演练。

我也希望,这种负面的和一般没有帮助的评论将不会被张贴。

谢谢你们的时间和帮助!

EN

回答 1

Stack Overflow用户

发布于 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。您已经知道widthheight被切换了几次。例如:当使用A4页面2次增加文档时,原始页面大小为210x297,需要将其更改为unitSize 148乘以210。换句话说,它需要缩小到系数148 / 210 (0.705)或210 / 297 (0.707)。在这种情况下,我们使用因子0.705。

我们可以像这样计算偏移量:

代码语言:javascript
复制
offsetX = unitSize.getWidth() * ((i % n) % c);
offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c);

如果您想对文档进行8次升级,c等于4。

代码语言:javascript
复制
(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()进行乘法。很明显,我们需要

代码语言:javascript
复制
offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c);

由于坐标系的性质:坐标系的起源在左下角。

我们调整offsetXoffsetY的一半的实际宽度差异的大小,向下页和可用的空间,以中心导入的页面。

你说你不想听到任何负面的评论。请允许我说一句:你的问题是,不是iText问题,也不是编程问题。这是一个数学问题。你真的需要在尝试编程之前学习数学,就像孩子在学会跑步之前需要学会走路一样。

造成混淆的一个可能原因可能是您没有考虑到ISO 216的一个特殊特性。该算法不适用于非标准页面。例如:如果您的页面是正方形,则不能将高度分为两部分并保持宽度。但这很明显,不是吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24974703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档