首页 > 解决方案 > 将添加图像到 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 实现的代码提出建议。

标签: itextpdfbox

解决方案


推荐阅读