使用java中的PDFBox在中心周围旋转PDF

时间:2016-11-15 14:00:23

标签: java pdfbox

PDDocument document = PDDocument.load(new File(input));
PDPage page = document.getDocumentCatalog().getPages().get(0);
PDPageContentStream cs = new PDPageContentStream(document, page,PDPageContentStream.AppendMode.PREPEND, false, false); 
cs.transform(Matrix.getRotateInstance(Math.toRadians(45), 0, 0));

我正在使用上面的代码来旋转PDF。

enter image description here

对于上面的图像,我得到以下输出

enter image description here

从该代码开始,页面的内容已经移出框架,并且旋转不会围绕其中心发生。但我希望得到输出

enter image description here

请给我一些选择。提前谢谢。

1 个答案:

答案 0 :(得分:10)

有两种主要方法可以旋转页面内容并使其显示在查看器中,就像旋转发生在可见页面的中间一样:任何一个实际上都是通过将旋转与翻译连接在一起实际旋转一个移动裁剪框,以便页面区域中心跟随旋转。

实际上围绕中心旋转

为此,我们在两个平移之间包围旋转,第一个将坐标系的原点移动到页面中心,第二个将其再次移回。

PDDocument document = PDDocument.load(resource);
PDPage page = document.getDocumentCatalog().getPages().get(0);
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false); 
PDRectangle cropBox = page.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
cs.transform(Matrix.getTranslateInstance(tx, ty));
cs.transform(Matrix.getRotateInstance(Math.toRadians(45), 0, 0));
cs.transform(Matrix.getTranslateInstance(-tx, -ty));
cs.close();

RotatePageContent test testRotateCenter

显然,您可以将矩阵相乘,只需向PDF添加一个转换。

沿着

拉动裁剪框

为此,我们计算页面中心的移动并相应地移动框。

PDDocument document = PDDocument.load(resource);
PDPage page = document.getDocumentCatalog().getPages().get(0);
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false);
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(45), 0, 0);
cs.transform(matrix);
cs.close();

PDRectangle cropBox = page.getCropBox();
float cx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float cy = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
Point2D.Float newC = matrix.transformPoint(cx, cy);
float tx = (float)newC.getX() - cx;
float ty = (float)newC.getY() - cy;
page.setCropBox(new PDRectangle(cropBox.getLowerLeftX() + tx, cropBox.getLowerLeftY() + ty, cropBox.getWidth(), cropBox.getHeight()));
PDRectangle mediaBox = page.getMediaBox();
page.setMediaBox(new PDRectangle(mediaBox.getLowerLeftX() + tx, mediaBox.getLowerLeftY() + ty, mediaBox.getWidth(), mediaBox.getHeight()));

RotatePageContent test testRotateMoveBox

将内容缩小到适合旋转后

如果想要缩小旋转的内容以使其完全合适,可以将其作为第一个变体的简单扩展:

PDDocument document = PDDocument.load(resource);
PDPage page = document.getDocumentCatalog().getPages().get(0);
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false);

Matrix matrix = Matrix.getRotateInstance(Math.toRadians(45), 0, 0);
PDRectangle cropBox = page.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;

Rectangle rectangle = cropBox.transform(matrix).getBounds();
float scale = Math.min(cropBox.getWidth() / (float)rectangle.getWidth(), cropBox.getHeight() / (float)rectangle.getHeight());

cs.transform(Matrix.getTranslateInstance(tx, ty));
cs.transform(matrix);
cs.transform(Matrix.getScaleInstance(scale, scale));
cs.transform(Matrix.getTranslateInstance(-tx, -ty));
cs.close();

RotatePageContent test testRotateCenterScale

更改裁剪框以使所有以前的页面区域保持可见

如果有人想改变裁剪框以使所有东西都适合而不进行缩放,可以将其作为第二种变体的简单扩展:

PDDocument document = PDDocument.load(resource);
PDPage page = document.getDocumentCatalog().getPages().get(0);
PDPageContentStream cs = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.PREPEND, false, false);
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(45), 0, 0);
cs.transform(matrix);
cs.close();

PDRectangle cropBox = page.getCropBox();
Rectangle rectangle = cropBox.transform(matrix).getBounds();
PDRectangle newBox = new PDRectangle((float)rectangle.getX(), (float)rectangle.getY(), (float)rectangle.getWidth(), (float)rectangle.getHeight());
page.setCropBox(newBox);
page.setMediaBox(newBox);

RotatePageContent test testRotateExpandBox

样本结果

下图显示了上述每种方法的输出:

Screenshot

  1. 实际上围绕中心旋转
  2. 在旋转后缩小内容以适应
  3. 沿着
  4. 拉动裁剪框
  5. 更改裁剪框以使所有以前的页面区域保持可见
  6. 图像4与其他图像的尺寸不同,它应该显示更大。