固定PDF的方向以缩放它

固定PDF的方向以缩放它,pdf,rotation,itext,scanning,Pdf,Rotation,Itext,Scanning,我对包含由Xerox扫描仪创建的旋转属性的PDF有一些问题。 下面的函数最初是用来根据变量scaleHeight给出的量来缩放输入PDF的高度的。 这适用于不旋转的输入文档 在测试270度旋转的文档时,我发现会使文档以纵向方向显示的旋转属性被忽略。相反,文档在输出PDF中以横向显示。 因此,我更新了下面的函数,仅在没有旋转的情况下应用缩放,并使用在线找到的另一个示例尝试修复旋转。 这不起作用,导致原始文档的镜像为纵向格式 现在我有两个问题: 1.如何正确旋转文档内容。 2.如何缩放旋转的内容 如

我对包含由Xerox扫描仪创建的旋转属性的PDF有一些问题。 下面的函数最初是用来根据变量scaleHeight给出的量来缩放输入PDF的高度的。 这适用于不旋转的输入文档

在测试270度旋转的文档时,我发现会使文档以纵向方向显示的旋转属性被忽略。相反,文档在输出PDF中以横向显示。 因此,我更新了下面的函数,仅在没有旋转的情况下应用缩放,并使用在线找到的另一个示例尝试修复旋转。 这不起作用,导致原始文档的镜像为纵向格式

现在我有两个问题: 1.如何正确旋转文档内容。 2.如何缩放旋转的内容

如果我可以解决项目1,我可以简单地再次调用函数(移除旋转属性)来修复项目2

感谢您的帮助,功能如下。 引用rotationEvent的注释掉的行在这里也没有帮助

public String resizePDF (String pdfIn, float x, float y, float scaleHeight) throws Exception {
    String pdfOut = pdfIn.substring(0, pdfIn.length() - 4) + "_resize.pdf";
    PdfReader reader = new PdfReader(pdfIn);
    int rotation = reader.getPageRotation(1);
    com.itextpdf.text.Document doc = new com.itextpdf.text.Document(reader.getPageSizeWithRotation(1), 0, 0, 0, 0);
    PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(pdfOut));
    doc.open();
    PdfContentByte cb = writer.getDirectContent();
    Rotate rotationEvent = new Rotate();
    writer.setPageEvent(rotationEvent);
    for(int i=1; i<=reader.getNumberOfPages(); i++){
        float pageWidth = reader.getPageSizeWithRotation(i).getWidth();
        float pageHeight = reader.getPageSizeWithRotation(i).getHeight();
        doc.newPage();
        PdfImportedPage page = writer.getImportedPage(reader, i);
        if (rotation == 0) {
            cb.addTemplate(page, 1f, 0, 0, scaleHeight, x, y);
            //rotationEvent.setRotation(PdfPage.PORTRAIT);
        } else if (rotation == 90) {
            cb.addTemplate(page, 0, -1f, 1f, 0, 0, pageHeight);
            //rotationEvent.setRotation(PdfPage.LANDSCAPE);
        } else if (rotation == 180) {
            cb.addTemplate(page, 1f, 0, 0, -1f, pageWidth, pageHeight);
            //rotationEvent.setRotation(PdfPage.INVERTEDPORTRAIT);
        } else if (rotation == 270) {
            cb.addTemplate(page, 0, -1f, 1f, 0, 0, pageHeight);
            //cb.addTemplate(page, 0, 1f, -1f, 0, pageWidth, 0);
            //rotationEvent.setRotation(PdfPage.SEASCAPE);
        }
    }
    doc.close();
    return pdfOut;
}
public String resizePDF(String pdfIn、float x、float y、float scalewhight)引发异常{
字符串pdfOut=pdfIn.substring(0,pdfIn.length()-4)+“_resize.pdf”;
PdfReader读取器=新PdfReader(pdfIn);
int rotation=reader.getPageRotation(1);
com.itextpdf.text.Document doc=new com.itextpdf.text.Document(reader.getPageSizeWithRotation(1,0,0,0);
PdfWriter writer=PdfWriter.getInstance(doc,新文件输出流(pdfOut));
doc.open();
PdfContentByte cb=writer.getDirectContent();
Rotate rotationEvent=新的Rotate();
writer.setPageEvent(rotationEvent);

例如(int i=1;i我不理解你的代码,但当我告诉人们“请扔掉你的代码,重新开始”时,许多人感到被冒犯(尽管我肯定不是有意冒犯他们)

我知道您想要缩放现有PDF的内容,或者保持旋转,或者删除它(这部分不完全清楚)

因此我给你们写了一个例子,这个例子可以用来缩小比例,保持方向。只需删除一行就可以删除方向

此示例使用一个页面事件(我将其命名为
ScaleEvent
):

创建事件时,传递一个值
scale
,该值将定义缩放因子。我将缩放应用于宽度和高度,如果您只想缩放高度,请随意调整

关于页面大小和旋转的信息存储在页面字典中。显然,
ScaleEvent
需要原始文档的值,这就是为什么我们将为复制的每个页面传递一个
pageDict

每次创建新页面时,我们都会复制/替换:

  • /Rotate
    值。如果要删除旋转,请删除此行
  • /MediaBox
    值。该值定义页面的完整大小
  • /CropBox
    值。该值定义页面的可见大小
当我们想要缩放页面时,我们使用以下
scaleDown()
方法:

public PdfArray scaleDown(PdfArray original, float scale) {
    if (original == null)
        return null;
    float width = original.getAsNumber(2).floatValue()
            - original.getAsNumber(0).floatValue();
    float height = original.getAsNumber(3).floatValue()
            - original.getAsNumber(1).floatValue();
    return new PdfRectangle(width * scale, height * scale);
}
假设我想将页面宽度和高度减少到原始宽度和高度的50%,那么我将创建如下事件:

PdfReader reader = new PdfReader(src);
float scale = 0.5f;
ScaleEvent event = new ScaleEvent(scale);
event.setPageDict(reader.getPageN(1));
我可以用我想要的任何页面大小定义
文档
,因为该大小将在
ScaleEvent
中更改。显然,要使其起作用,我需要向
PdfWriter
实例声明事件:

Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
writer.setPageEvent(event);
document.open();
现在只需要在页面上循环:

int n = reader.getNumberOfPages();
Image page;
for (int p = 1; p <= n; p++) {
    page = Image.getInstance(writer.getImportedPage(reader, p));
    page.setAbsolutePosition(0, 0);
    page.scalePercent(scale * 100);
    document.add(page);
    if (p < n) {
        event.setPageDict(reader.getPageN(p + 1));
    }
    document.newPage();
}
document.close();

你的问题可能没有得到答案,因为它非常混乱。不清楚你想达到什么目的。几页最初有一个轮换。这很好。现在你为什么要删除这个轮换?你还说“它不起作用”通常没有任何进一步的解释,但例如:这与您试图做的类似吗?我最初的目标只是缩放输入PDF。当我看到输出PDF有不同的方向时,我意识到旋转属性导致了问题。这是我开始删除旋转属性并实际操作的时候修复页面的方向,以便可以进行正常缩放。注意到它不起作用的原因-输出文档成为输入的镜像。您链接的内容与我想做的类似。在我的情况下,我希望能够删除旋转属性(因为它显然与cb.addTemplate不兼容)和物理更改文档内容以永久显示为纵向。是否有更简单的解决方案来缩放任何输入文档,而不管是否应用了旋转?为什么不将
PdfImportedPage
包装成
图像
(别担心,您不会使用任何质量),使用图像上的缩放方法,并将图像添加到您定义的大小等于图像缩放大小的页面中?感谢您花时间编写此解决方案,您是对的,我误解了图像类的用法。不幸的是,使用此解决方案,页面方向正确,但内容是still横向旋转,由于空间不足而被切断。我已删除了私人信息以创建以下测试PDF:注意:我还尝试添加对page.setRotation的调用,但没有效果。最后,我认为有必要使用某些页面大小初始化新文档:com.itextpdf.text.document doc=new com.itextpdf.text.Document(reader.getPageSizeWithRotation(1),0,0,0,0);让我知道查看这个麻烦的输入文档的相应输出PDF是否有帮助。也许你可以共享它。我不同意是否用页面大小初始化新文档很重要。大小
int n = reader.getNumberOfPages();
Image page;
for (int p = 1; p <= n; p++) {
    page = Image.getInstance(writer.getImportedPage(reader, p));
    page.setAbsolutePosition(0, 0);
    page.scalePercent(scale * 100);
    document.add(page);
    if (p < n) {
        event.setPageDict(reader.getPageN(p + 1));
    }
    document.newPage();
}
document.close();
writer.addPageDictEntry(PdfName.ROTATE, pageDict.getAsNumber(PdfName.ROTATE));