【问题标题】:PDF scaling/importing pages that have been trimmed/croppedPDF 缩放/导入已修剪/裁剪的页面
【发布时间】:2013-08-28 08:08:54
【问题描述】:

我目前正在编写一个应用程序,使用 iText 2.1.7 根据我们的要求“格式化”PDF。

我们基本上采用纵向 PDF,并缩小页面,因此我们可以将原始 PDF 的 2 页放在新 PDF 的一个横向页面上。我们还在页面底部留了一些空间用于后期处理。

这个过程在 90% 的时间里都能正常工作。

但是,我们收到了一个已被内容部门裁剪/修剪的 PDF,当我们在 Acrobat 中查看此 PDF 时,它看起来与预期的一样。但是,当我们处理它时,新的 PDF 会包含整个原始 MediaBox 和裁剪线。

这是我们使用的代码,以及问题输出的样子。

File tempFile = new File(tempFilename);
PdfReader reader = new PdfReader(originalPdfFile);
Document doc = new Document(new RectangleReadOnly(842f, 595f), 0, 0, 0, 0);
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(tempFile));
doc.open();
for (int i = 1; i < reader.getNumberOfPages(); i = i + 2) {
    doc.newPage();
    PdfContentByte cb = writer.getDirectContent();
    PdfImportedPage page = writer.getImportedPage(reader, i); // page #1

    float documentWidth = doc.getPageSize().getWidth() / 2;
    float documentHeight = doc.getPageSize().getHeight() - 65f;

    float pageWidth = page.getWidth();
    float pageHeight = page.getHeight();

    float widthScale = documentWidth / pageWidth;
    float heightScale = documentHeight / pageHeight;
    float scale = Math.min(widthScale, heightScale);

    float offsetX = (documentWidth - (pageWidth * scale)) / 2;
    float offsetY = 65f; //100f

    cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);

    PdfImportedPage page2 = writer.getImportedPage(reader, i+1); // page #2

    pageWidth = page.getWidth();
    pageHeight = page.getHeight();

    widthScale = documentWidth / pageWidth;
    heightScale = documentHeight / pageHeight;
    scale = Math.min(widthScale, heightScale);

    offsetX = ((documentWidth - (pageWidth * scale)) / 2) + documentWidth;
    offsetY = 65f; //100f

    cb.addTemplate(page2, scale, 0, 0, scale, offsetX, offsetY);//430f
    }

doc.close();

acrobat 中的原创:

在 acrobat 中修改,显示不需要的 pretrim 内容:

【问题讨论】:

    标签: java pdf pdf-generation itext


    【解决方案1】:

    虽然如果不查看 PDF 本身就很难确定,但我怀疑您的问题是该 PDF 至少在其某些页面上指定了 CropBox。如果是这种情况,那么我认为您会在获得页面参考后立即执行page.setBoundingBox(reader.getCropBox(i)); 之类的操作。

    请注意,页面CropBox 的默认值为MediaBox,因此添加上述行不会对未指定CropBox 的PDF 页面的布局产生负面影响。

    (我不是 iText 用户,所以这是我的一些猜测......)

    祝你好运!

    【讨论】:

      【解决方案2】:

      在经历了很多挫折之后,我终于在进行缩放和布局处理之前通过“硬裁剪”PDF 来完成这项工作。

      硬裁剪采用 Acrobat 裁剪的 PDF(裁剪 = 隐藏),并使用 PdfStamper 创建仅包含裁剪框内内容的新 PDF。

      public String cropPdf(String pdfFilePath) throws DocumentException, IOException {
          String filename = FilenameUtils.getBaseName(pdfFilePath) + "_cropped." + FilenameUtils.getExtension(pdfFilePath);
          filename = FilenameUtils.concat(System.getProperty("java.io.tmpdir"), filename);
          PdfReader reader = new PdfReader(pdfFilePath);
          try {
              PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(filename));
              try {
                  for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                      PdfDictionary pdfDictionary = reader.getPageN(i);
                      PdfArray cropArray = new PdfArray();
                      Rectangle cropbox = reader.getCropBox(i);                   
                      cropArray.add(new PdfNumber(cropbox.getLeft()));
                      cropArray.add(new PdfNumber(cropbox.getBottom()));
                      cropArray.add(new PdfNumber(cropbox.getLeft() + cropbox.getWidth()));
                      cropArray.add(new PdfNumber(cropbox.getBottom() + cropbox.getHeight()));
                      pdfDictionary.put(PdfName.CROPBOX, cropArray);
                      pdfDictionary.put(PdfName.MEDIABOX, cropArray);
                      pdfDictionary.put(PdfName.TRIMBOX, cropArray);
                      pdfDictionary.put(PdfName.BLEEDBOX, cropArray);
                  }
                  return filename;
              } finally {
                  stamper.close();
              }
          } finally {
              reader.close();
          }
      }
      

      【讨论】:

        【解决方案3】:

        对 Kabals 答案的一个小而重要的修复:盒子期望宽度/高度而不是坐标:

                    ...
                    cropArray.add(new PdfNumber(cropbox.getLeft()));
                    cropArray.add(new PdfNumber(cropbox.getBottom()));
                    cropArray.add(new PdfNumber(cropbox.getWidth()));
                    cropArray.add(new PdfNumber(cropbox.getHeight()));
                    ...
        

        【讨论】:

          猜你喜欢
          • 2011-03-23
          • 2010-10-02
          • 2014-12-19
          • 1970-01-01
          • 2012-10-17
          • 2015-06-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多