itext - 将添加图像到 pdf 从 iText 迁移到 PDFBox
问题描述
在我们的项目中,我们使用 iText 5.x 版本来操作 PDF 文件并使用 PDFBox 2.x 版本迁移该实现。
有一个向 pdf 页面添加图像的场景,我已经尽我所能将该代码转换为 PDFBox。:) 在现有实现(iText)中,他们使用 PdfTemplate 在模板中添加图像,并使用 PdfAnnotation 类在注释中添加该模板。
我不知道如何使用 PDFBox 做到这一点。另外请检查我是否正确迁移了现有实现,因为我是使用 Java 的 PDF 库中的新手。
将图像添加到 PDF(使用 iText):
Document document = null;
PdfReader pdfReader = null;
pdfReader = new PdfReader(SourceFilePath());
//we retrieve the total number of pages and the page size
int total = pdfReader.getNumberOfPages();
Rectangle rectangle = pdfReader.getPageSizeWithRotation(1);
document = new Document(rectangle);
PdfImportedPage page;
PdfCopy.PageStamp stamp;
// step 2: we create a PdfCopy object that listens to the document.
PdfCopy copy = new PdfCopy(document, new FileOutputStream(DestinationFilePath(false));
document.open();
// step 4: adding the content
for (int i = 1; i <= total; i++) {
page = copy.getImportedPage(pdfReader, i);
if(i == 1 || aBarcodeVO.getDisplacementVO().isApplyForAllPages()){
BufferedImage bufferedImage = getImage();
Image img = Image.getInstance(bufferedImage, null);
img.scaleToFit(qrImageSize, qrImageSize);
PdfName imgKey = new PdfName(aBarcodeVO.getImgUniqueId() + i);
Rectangle rectPage = pdfReader.getPageSizeWithRotation(i);
stamp = copy.createPageStamp(page);
PdfImage stream = new PdfImage(img, "", null);
stream.put(imgKey, imgKey);
PdfIndirectObject ref = copy.addToBody(stream);
int rotation = pdfReader.getPageRotation(i);
Rectangle cropBoxRect = pdfReader.getCropBox(i);;
//Explicitly Apply rotation to crop box rectangle.
for (int j = 0; j < (rotation/90); j++) {
cropBoxRect = cropBoxRect.rotate();
}
//added Image in template and template in Annotation and finally annotation is added in PDF through PdfCopy.PageStamp
PdfTemplate template = PdfTemplate.createTemplate(copy, img.getPlainWidth(), img.getPlainHeight());
img.setAbsolutePosition(0, 0);
img.setRotationDegrees(rotation);
img.setDirectReference(ref.getIndirectReference());
template.addImage(img);
Rectangle rect = new Rectangle(rectLlx, rectLly, rectUrx, rectUry);
rect.setBorderWidth(0.5f);
rect.setBorderColor(new BaseColor(0xFF, 0x00, 0x00));
PdfAnnotation annotation = PdfAnnotation.createStamp(copy, rect, null, "AnnotationOnly");
annotation.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, template);
annotation.setFlags(PdfAnnotation.FLAGS_PRINT + PdfAnnotation.FLAGS_LOCKED);
annotation.setRotate(rotation);
PdfName annotKey = getAnnotKey(i);
annotation.put(annotKey, annotKey);
stamp.addAnnotation(annotation);
stamp.alterContents();
}
copy.addPage(page);
}
copy.freeReader(pdfReader);
try {
if (document != null) {
document.close();
}
} catch (Exception e) {
System.out.println("Exception in handleAddBarCode() while closing():document:" + e);
}
try {
if (pdfReader != null) {
pdfReader.close();
}
} catch (Exception e) {
System.out.println("Exception in handleAddBarCode() while closing():pdfReader:" + e);
}
将图像添加到 PDF(使用 PDFBox):
PDDocument pdDocument = PDDocument.load(new File(SourceFilePath()));
int total = pdDocument.getNumberOfPages();
PDPage page = pdDocument.getDocumentCatalog().getPages().get(0);
PDRectangle rectangle = getRotatedMediaBox(page);
PDPage pdPage = new PDPage(rectangle);
PDDocument newDocument = new PDDocument();
for (int i = 0; i < total; i++) {
pdPage = newDocument.importPage(pdDocument.getPage(i));
PDRectangle pageRect = getRotatedMediaBox(pdPage);
int rotation = pdPage.getRotation();
PDRectangle cropBoxRect = page.getCropBox();
//Calculate margin between crop box rectangle and page rectangle.
float[] margins = getCropBoxMargin(pageRect, cropBoxRect, rotation);
if (rotation == 90 || rotation == 270) {
cropBoxRect = new PDRectangle(cropBoxRect.getLowerLeftY(), cropBoxRect.getLowerLeftX(), cropBoxRect.getHeight(),
cropBoxRect.getWidth());
}
BufferedImage bufferedImage = getImage();
PDPageContentStream pageContentStream = new PDPageContentStream(newDocument, pdPage,
PDPageContentStream.AppendMode.APPEND, true);
PDImageXObject image = JPEGFactory.createFromImage(newDocument, bufferedImage);
if (rotation == 90 || rotation == 270) {
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0);
PDRectangle cropBox = pdPage.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
Rectangle rectang = cropBox.transform(matrix).getBounds();
float scale = Math.min(cropBox.getWidth() / (float)rectang.getWidth(), cropBox.getHeight() / (float)rectang.getHeight());
pageContentStream.transform(Matrix.getTranslateInstance(tx, ty));
pageContentStream.transform(matrix);
pageContentStream.transform(Matrix.getScaleInstance(scale, scale));
pageContentStream.transform(Matrix.getTranslateInstance(-tx, -ty));
}
pageContentStream.drawImage(image, rectLlx, rectLly, qrImageSize, qrImageSize);
pageContentStream.close();
}
newDocument.save(new File(DestinationFilePath(false)));
newDocument.close();
pdDocument.close();
请在这方面帮助我,或者至少期待您对需要纠正 PDFBox 实现的代码提出建议。
解决方案
推荐阅读
- amazon-web-services - 为 IAM 用户角色信任策略定义委托人时的困惑
- microsoft-graph-api - 用于使 OneNote 页面不起作用的 Microsoft 图形 API
- python-3.x - 在张量流数据集上应用地图执行非常缓慢
- swift - 在 Xcode 中,什么可以让程序使用断点,但不是没有?
- python - 熊猫如何将txt文件作为列表导入
- python - 使用 QThread 和 pyqtSignal,为什么不同线程中的进程会冻结 GUI?
- javascript - 如何将附加路径附加到我的 JSON 文件中的嵌套对象,路径的前半部分存储在变量中?
- python - Flask 和 BytesIO:将文件输出为流的问题
- scala - sbt-assembly spark 不工作,但 sbt run 可以
- python - 当Apply方法返回多行时,Pandas Store DataFrame