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。
对于上图,我得到以下输出
从该代码来看,页面内容已移出框架,并且没有围绕其中心旋转。但我想得到输出为
请给我一些建议。提前致谢。
最佳答案
有两种主要方法可以旋转页面内容并使其在查看器中看起来好像旋转发生在可见页面的中间:通过将旋转与翻译连接起来实际上确实围绕页面中间旋转,或者移动裁剪框,使页面区域中心跟随旋转。
实际围绕中心旋转
为此,我们包络了两个平移之间的旋转,第一个将坐标系的原点移至页面中心,第二个将其再次移回。
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 测试 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 测试 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 测试 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 测试 testRotateExpandBox
)
示例结果
下图显示了上述每种方法的输出:
- 实际围绕中心旋转
- 旋转后缩小内容以适应
- 拉动裁剪框
- 更改裁剪框以使之前的所有页面区域保持可见
图 4 与其他图片的比例不一样,应该显示大一些。
关于java - 在java中使用PDFBox围绕其中心旋转PDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40611736/