Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java PDF页面大小,图像更宽_Java_Pdf_Pdfbox - Fatal编程技术网

Java PDF页面大小,图像更宽

Java PDF页面大小,图像更宽,java,pdf,pdfbox,Java,Pdf,Pdfbox,我使用PDF框处理PDF文件,并根据页面上给定的坐标插入文本对象。我得到的坐标是基于左上角的,我找到页面的媒体框,然后计算文本的位置。然而,有些PDF图像(它们被扫描)我插入的文本不在正确的位置,比如页面的大小比我使用media box时得到的要大得多 // getX-Y returns the coordinates that the text should be inserted // getSize returns the text height void write(PDDocument

我使用PDF框处理PDF文件,并根据页面上给定的坐标插入文本对象。我得到的坐标是基于左上角的,我找到页面的媒体框,然后计算文本的位置。然而,有些PDF图像(它们被扫描)我插入的文本不在正确的位置,比如页面的大小比我使用media box时得到的要大得多

// getX-Y returns the coordinates that the text should be inserted
// getSize returns the text height
void write(PDDocument doc, PDPage page, PDPageContentStream cs) {
    PDRectangle rect = page.findMediaBox();
    cs.moveTextPositionByAmount(this.getX(), height-this.getY()-getSize());
}
从媒体盒检索到的尺寸为
595.2 x 841.92
。对于给定的文本位置<代码> 300×420 ,我期望将文本插入到页面的中间。但是,它插入的方式太低,页面左侧。当我用Acrobat Reader打开文档并将页面复制为图像时(因为已扫描),我看到图像尺寸为
2480 x 3508
。如果页面尺寸为该尺寸,则插入文本的位置将有意义

我觉得pdf页面大小会根据它的内容而改变,但是为什么我不把这些尺寸作为页面大小,而仍然得到类似于
595.2 x 841.92
的东西呢?我是否应该处理页面上的每个图像并找到真正的尺寸?我错过了什么

编辑:

编辑: 这是我得到的代码部分
PDPageContentStream

PDDocument doc = null;
doc = PDDocument.load(inputFile);
List <?> allPages = doc.getDocumentCatalog().getAllPages();
for (int i = 0; i < list.size(); i++) {
    PDFObject obj = (PDFObject) list.get(i);
    for (int j = 0; j < allPages.size(); j++) {
        PDPage page = (PDPage) allPages.get(j);
        PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true);
        obj.write(doc, page, contentStream);
        if ("F".equalsIgnoreCase(obj.getPageType())) {
            break;
        }
    }
}
PDDocument doc=null;
doc=PDDocument.load(输入文件);
List allPages=doc.getDocumentCatalog().getAllPages();
对于(int i=0;i
不幸的是,OP没有发布所有相关代码。因此,这个答案部分基于假设,特别是他创建了他的
PDPageContentStream
,但没有确保默认用户空间坐标系仍在他添加新操作的位置使用

示例文档 第一页的内容流如下所示开始:

0.24000 0 0 0.24000 0 0 cm
q
2480 0 0 3508 0 0 cm
/Im5 Do
Q
因此,它首先按
.24
缩放用户空间坐标系,推动图形状态,按
2480
(x方向)和
3508
(y方向)缩放坐标系,绘制图像,并最终恢复图形状态

因此,此后用户空间坐标系仍按
.24
缩放。因此,以下操作中给出的坐标受该因素的影响

紧跟其后的是文本对象,例如:

BT
1 0 0 rg
/F0 25 Tf
400 794.9199829102 Td
(JFE14006) Tj
ET 
我假设这是OP添加的对象之一,没有考虑非默认用户空间坐标系,因为坐标和字体大小似乎适合默认用户空间坐标系

(顺便说一句,引用的字体未在页面的资源字典中定义。)

解决方案1 由于插入点处的用户空间坐标系按.24进行缩放,因此您可以反缩放自己的坐标和大小(即,将它们除以.24)

例如,要使用大小为10的字体在给定的文本位置300x420(左上角的原点)绘制文本“中间”,可以执行以下操作:

PDDocument document = PDDocument.load("0006-sun1-4.pdf");
List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = allPages.get(0);
PDRectangle pageSize = firstPage.findMediaBox();

PDPageContentStream contentStream = new PDPageContentStream(document, firstPage, true, true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300/.24f, (pageSize.getUpperRightY() - 420 - 10)/.24f);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10/.24f);
contentStream.drawString("MIDDLE");
contentStream.endText();
contentStream.close();

document.save("0006-sun1-4-scaledAdd.pdf");
document.close();
PDDocument document = PDDocument.load("0006-sun1-4.pdf");
List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = allPages.get(0);
PDRectangle pageSize = firstPage.findMediaBox();

PDStream contents = firstPage.getContents();  
PDFStreamParser parser = new PDFStreamParser(contents.getStream()); 
parser.parse();
List<Object> tokens = parser.getTokens();
tokens.add(0, PDFOperator.getOperator("q"));
tokens.add(PDFOperator.getOperator("Q"));
PDStream updatedStream = new PDStream(document);  
OutputStream out = updatedStream.createOutputStream();  
ContentStreamWriter tokenWriter = new ContentStreamWriter(out);  
tokenWriter.writeTokens(tokens);  
firstPage.setContents(updatedStream);

PDPageContentStream contentStream = new PDPageContentStream(document, firstPage, true, true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300, pageSize.getUpperRightY() - 420 - 10);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
contentStream.drawString("MIDDLE");
contentStream.endText();
contentStream.close();

document.save("0006-sun1-4-restoredAdd.pdf");
document.close();
PDDocument document=PDDocument.load(“0006-sun1-4.pdf”);
List allPages=document.getDocumentCatalog().getAllPages();
PDPage firstPage=allPages.get(0);
PDRectangle pageSize=firstPage.findMediaBox();
PDPageContentStream contentStream=新的PDPageContentStream(document,firstPage,true,true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300/.24f,(pageSize.getUpperRightY()-420-10)/.24f);
contentStream.setFont(PDType1Font.HELVETICA_粗体,10/.24f);
contentStream.抽绳(“中间”);
contentStream.endText();
contentStream.close();
文件保存(“0006-sun1-4-scaledd.pdf”);
document.close();
不过,该解决方案并非最佳方案:

  • 一旦您拥有另一个源文档(例如更新的表单),插入点处的内容流可能具有不同比例的坐标系
  • 图形绘图引擎的其他状态也可能未处于您期望的默认状态
因此:

解决方案2 通过使用q(保存图形状态)和q(恢复图形状态)操作符对封闭现有内容流,可以将所有更改还原为图形状态

例如,如上所述,要使用大小为10的字体在给定文本位置300x420(左上角的原点)绘制文本“中间”,可以执行以下操作:

PDDocument document = PDDocument.load("0006-sun1-4.pdf");
List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = allPages.get(0);
PDRectangle pageSize = firstPage.findMediaBox();

PDPageContentStream contentStream = new PDPageContentStream(document, firstPage, true, true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300/.24f, (pageSize.getUpperRightY() - 420 - 10)/.24f);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10/.24f);
contentStream.drawString("MIDDLE");
contentStream.endText();
contentStream.close();

document.save("0006-sun1-4-scaledAdd.pdf");
document.close();
PDDocument document = PDDocument.load("0006-sun1-4.pdf");
List<PDPage> allPages = document.getDocumentCatalog().getAllPages();
PDPage firstPage = allPages.get(0);
PDRectangle pageSize = firstPage.findMediaBox();

PDStream contents = firstPage.getContents();  
PDFStreamParser parser = new PDFStreamParser(contents.getStream()); 
parser.parse();
List<Object> tokens = parser.getTokens();
tokens.add(0, PDFOperator.getOperator("q"));
tokens.add(PDFOperator.getOperator("Q"));
PDStream updatedStream = new PDStream(document);  
OutputStream out = updatedStream.createOutputStream();  
ContentStreamWriter tokenWriter = new ContentStreamWriter(out);  
tokenWriter.writeTokens(tokens);  
firstPage.setContents(updatedStream);

PDPageContentStream contentStream = new PDPageContentStream(document, firstPage, true, true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300, pageSize.getUpperRightY() - 420 - 10);
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 10);
contentStream.drawString("MIDDLE");
contentStream.endText();
contentStream.close();

document.save("0006-sun1-4-restoredAdd.pdf");
document.close();
PDDocument document=PDDocument.load(“0006-sun1-4.pdf”);
List allPages=document.getDocumentCatalog().getAllPages();
PDPage firstPage=allPages.get(0);
PDRectangle pageSize=firstPage.findMediaBox();
PDStream contents=firstPage.getContents();
PDFStreamParser=新的PDFStreamParser(contents.getStream());
parser.parse();
List tokens=parser.getTokens();
add(0,PDFOperator.getOperator(“q”);
add(PDFOperator.getOperator(“Q”));
PDStream updatedStream=新PDStream(文档);
OutputStream out=updatedStream.createOutputStream();
ContentStreamWriter tokenWriter=新的ContentStreamWriter(输出);
tokenWriter.writeTokens(代币);
firstPage.setContents(updatedStream);
PDPageContentStream contentStream=新的PDPageContentStream(document,firstPage,true,true);
contentStream.setStrokingColor(Color.red);
contentStream.beginText();
contentStream.moveTextPositionByAmount(300,pageSize.getUpperRightY()-420-10);
contentStream.setFont(PDType1Font.HELVETICA_粗体,10);
contentStream.抽绳(“中间”);
contentStream.endText();
contentStream.close();
文件保存(“0006-sun1-4-restoredAdd.pdf”);
document.close();
(帕斯)