PDF 收缩导致方向改变
PDF Shrink causing change in Orientation
我正在使用以下代码缩小 pdf。缩小前 PDF 页面可以纵向看到,但缩小后它们的方向变为横向。当我在缩小之前打印页面旋转时,它会变成 270 度。收缩后页面旋转的原因是什么? (我要缩小的 PDF 有旧的扫描图像)
public void shrinkPDF(String strFilePath , String strFileName) throws Exception {
PdfReader reader = new PdfReader(strFilePath+"//"+strFileName);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(strFilePath+"//Shrink_"+strFileName));
int n = reader.getNumberOfPages();
for (int p = 1; p <= 1; p++) {
float offsetX = (reader.getPageSize(p).getWidth() * (1 - xPercentage)) / 2;
float offsetY = (reader.getPageSize(p).getHeight() * (1 - yPercentage)) / 2;
PdfDictionary page;
PdfArray crop;
PdfArray media;
page = reader.getPageN(p);
System.out.println("reader.getPateRoatation-->"+reader.getPageRotation(p));
media = page.getAsArray(PdfName.CROPBOX);
if (media == null) {
media = page.getAsArray(PdfName.MEDIABOX);
}
crop = new PdfArray();
crop.add(new PdfNumber(0));
crop.add(new PdfNumber(0));
crop.add(new PdfNumber(media.getAsNumber(2).floatValue()));
crop.add(new PdfNumber(media.getAsNumber(3).floatValue()));
page.put(PdfName.MEDIABOX, crop);
page.put(PdfName.CROPBOX, crop);
Rectangle mediabox = reader.getPageSize(p);
stamper.getUnderContent(p).setLiteral(
String.format("\nq %s %s %s %s %s %s cm\nq\n",
xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage, offsetX, offsetY));
stamper.getOverContent(p).setLiteral("\nQ\nQ\n");
}
stamper.close();
reader.close();
}
原因
问题的原因是 iText 的一个特性:
iText 尝试通过旋转当前转换矩阵来启动内容过多和内容不足,从而简化向旋转页面添加信息的过程。这使得添加到页面的内容在 PDF 查看器中显示为直立,而无需添加单独的旋转。
即使底部内容是在原始页面内容之前绘制的,这通常对原始内容没有影响,因为整个底部内容都包含在保存图形状态/恢复图形状态指令对中。
不过,您用作底层内容的文字包含两个保存图形状态指令,但没有恢复图形状态指令。这使得添加的旋转也会突然影响原始内容。因此,即使您只想缩放,您的原始内容也会旋转。
修复
iText 允许您关闭上述功能。您可以在创建 PdfStamper
:
后立即将 PdfStamper
属性 RotateContents
设置为 false
PdfStamper stamper = new PdfStamper(reader, result);
stamper.setRotateContents(false);
int n = reader.getNumberOfPages();
现在 iText 不会再将旋转添加到内容不足的部分,并且只会缩放您的原始内容。
PdfStamper
属性 RotateContents
已在 中进行了更深入的讨论。
注释注意事项
iText 不仅将旋转添加到页面内容流的内容不足和内容过多,它还操纵添加到旋转页面的注释的尺寸,不幸的是 PdfStamper
属性 RotateContents
没有考虑在内。
这种情况下的解决方法是在将注释添加到页面之前暂时删除页面 Rotation 条目,稍后再将其放回原位。这已经在 , , and .
中进行了更详细的讨论
您的剩余代码
您对裁剪框和媒体框的更改似乎没有必要,并且可能会产生意想不到的结果。
你这样添加收缩:
stamper.getUnderContent(p).setLiteral(
String.format("\nq %s %s %s %s %s %s cm\nq\n",
xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage, offsetX, offsetY));
将第二个和第三个参数分别设置为mediabox.getLeft()
和mediabox.getBottom()
通常不会有什么坏影响(因为这些值通常为0)但在某些情况下你会体验到极度扭曲的视图(放大的部分)您的页面。
我正在使用以下代码缩小 pdf。缩小前 PDF 页面可以纵向看到,但缩小后它们的方向变为横向。当我在缩小之前打印页面旋转时,它会变成 270 度。收缩后页面旋转的原因是什么? (我要缩小的 PDF 有旧的扫描图像)
public void shrinkPDF(String strFilePath , String strFileName) throws Exception {
PdfReader reader = new PdfReader(strFilePath+"//"+strFileName);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(strFilePath+"//Shrink_"+strFileName));
int n = reader.getNumberOfPages();
for (int p = 1; p <= 1; p++) {
float offsetX = (reader.getPageSize(p).getWidth() * (1 - xPercentage)) / 2;
float offsetY = (reader.getPageSize(p).getHeight() * (1 - yPercentage)) / 2;
PdfDictionary page;
PdfArray crop;
PdfArray media;
page = reader.getPageN(p);
System.out.println("reader.getPateRoatation-->"+reader.getPageRotation(p));
media = page.getAsArray(PdfName.CROPBOX);
if (media == null) {
media = page.getAsArray(PdfName.MEDIABOX);
}
crop = new PdfArray();
crop.add(new PdfNumber(0));
crop.add(new PdfNumber(0));
crop.add(new PdfNumber(media.getAsNumber(2).floatValue()));
crop.add(new PdfNumber(media.getAsNumber(3).floatValue()));
page.put(PdfName.MEDIABOX, crop);
page.put(PdfName.CROPBOX, crop);
Rectangle mediabox = reader.getPageSize(p);
stamper.getUnderContent(p).setLiteral(
String.format("\nq %s %s %s %s %s %s cm\nq\n",
xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage, offsetX, offsetY));
stamper.getOverContent(p).setLiteral("\nQ\nQ\n");
}
stamper.close();
reader.close();
}
原因
问题的原因是 iText 的一个特性:
iText 尝试通过旋转当前转换矩阵来启动内容过多和内容不足,从而简化向旋转页面添加信息的过程。这使得添加到页面的内容在 PDF 查看器中显示为直立,而无需添加单独的旋转。
即使底部内容是在原始页面内容之前绘制的,这通常对原始内容没有影响,因为整个底部内容都包含在保存图形状态/恢复图形状态指令对中。
不过,您用作底层内容的文字包含两个保存图形状态指令,但没有恢复图形状态指令。这使得添加的旋转也会突然影响原始内容。因此,即使您只想缩放,您的原始内容也会旋转。
修复
iText 允许您关闭上述功能。您可以在创建 PdfStamper
:
PdfStamper
属性 RotateContents
设置为 false
PdfStamper stamper = new PdfStamper(reader, result);
stamper.setRotateContents(false);
int n = reader.getNumberOfPages();
现在 iText 不会再将旋转添加到内容不足的部分,并且只会缩放您的原始内容。
PdfStamper
属性 RotateContents
已在
注释注意事项
iText 不仅将旋转添加到页面内容流的内容不足和内容过多,它还操纵添加到旋转页面的注释的尺寸,不幸的是 PdfStamper
属性 RotateContents
没有考虑在内。
这种情况下的解决方法是在将注释添加到页面之前暂时删除页面 Rotation 条目,稍后再将其放回原位。这已经在
您的剩余代码
您对裁剪框和媒体框的更改似乎没有必要,并且可能会产生意想不到的结果。
你这样添加收缩:
stamper.getUnderContent(p).setLiteral( String.format("\nq %s %s %s %s %s %s cm\nq\n", xPercentage, mediabox.getLeft(),mediabox.getBottom(), yPercentage, offsetX, offsetY));
将第二个和第三个参数分别设置为
mediabox.getLeft()
和mediabox.getBottom()
通常不会有什么坏影响(因为这些值通常为0)但在某些情况下你会体验到极度扭曲的视图(放大的部分)您的页面。