企业级-PDF图片水印

作者:fyupeng

技术专栏:☞ https://github.com/fyupeng

项目地址:☞ https://github.com/fyupeng/distributed-blog-system-api


留给读者

遇到签名,往往很无奈签名的位置、大小。

一、介绍

直接提供PDF路径和图片路径,以及输出路径,就可以完成需要的需求,关键字也可以作为参数传入,根据自行需求修改。

二、代码

java 复制代码
public class PdfBuilderUtil {
    public static void imageWatermark(String inputPath, String outputPath,String imagePath) throws IOException, com.itextpdf.text.DocumentException {
        PdfReader reader = new PdfReader(inputPath);
        PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(outputPath));
        PdfGState gs1 = new PdfGState();
        gs1.setFillOpacity(0.1f);

        InputStream imageIS = new FileInputStream(imagePath);
        Image image = Image.getInstance(IOUtils.toByteArray(imageIS));
        int n = reader.getNumberOfPages();

        InputStream inputStream = new FileInputStream(inputPath);
        PDDocument document = PDDocument.load(inputStream);
        for(int i=1;i<=n;i++){
            PdfContentByte pdfContentByte = stamp.getOverContent(i);
            // 默认图片水印大小,详见盖章右下角大小样例
            image.scalePercent(75f);
            // 默认图片水印横坐标,详见盖章右下角横坐标
            float absoluteX = 370;
            // 默认图片水印纵坐标,高度中间位置
            float absoluteY = (PageSize.POSTCARD.getHeight() - image.getScaledHeight())/2;
            
            float[] xyz = getKeyWords(reader, "盖章位置");
            if (xyz != null && xyz.length >= 3) {
                //新版文书
                absoluteY = xyz[1];
            } else {
                //旧版文书
                float[] oldXyz = getKeyWords(reader, "其他位置");
                if (oldXyz != null && oldXyz.length >= 3) {
                    absoluteY = oldXyz[2]+300;
                }
            }

            // 读取图像文件
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setStartPage(i); // Page indexes are 1-based in PDFTextStripper
            stripper.setEndPage(i);
            String text = stripper.getText(document);

            if (!text.trim().isEmpty()) {
                image.setAbsolutePosition(absoluteX, absoluteY);
                pdfContentByte.addImage(image);
            }
        }

        inputStream.close();
        imageIS.close();
        stamp.close();
        reader.close();
    }

    /**
     * 根据关键字定位
     * @param pdfReader
     * @param keyWords
     * @return
     */
    public  static float[] getKeyWords(PdfReader pdfReader, String keyWords) {
        float[] coordinate = null;
        int page = 0;
        try{
            int pageNum = pdfReader.getNumberOfPages();
            PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
            CustomRenderListener renderListener = new CustomRenderListener();
            renderListener.setKeyWord(keyWords);
            for (page = 1; page <= pageNum; page++) {
                renderListener.setPage(page);
                pdfReaderContentParser.processContent(page, renderListener);
                coordinate = renderListener.getPcoordinate();
                if (coordinate != null) break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return coordinate;
    }
    
}

pdf签名帮助类

java 复制代码
public class CustomRenderListener implements RenderListener{

    private float[] pcoordinate = null;

    private String keyWord;

    private int page;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public float[] getPcoordinate(){
        return pcoordinate;
    }

    public String getKeyWord() {
        return keyWord;
    }

    public void setKeyWord(String keyWord) {
        this.keyWord = keyWord;
    }

    @Override
    public void beginTextBlock() {}

    @Override
    public void endTextBlock() {}

    @Override
    public void renderImage(ImageRenderInfo arg0) {}

    @Override
    public void renderText(TextRenderInfo textRenderInfo) {
        String text = textRenderInfo.getText();
        if (null != text && text.contains(keyWord)) {
            Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
            pcoordinate = new float[3];
            pcoordinate[0] = boundingRectange.x;
            pcoordinate[1] = boundingRectange.y;
            pcoordinate[2] = page;
        }
    }
}

三、总结

简洁、高效、精炼!

相关推荐
FinelyYang2 天前
uniapp使用kkfileview在线预览ppt,excel,word,pdf类型文件
pdf·uni-app·powerpoint
WORLDPO92262 天前
QTE-020-01-L/F/C-D-A-K-TR_实物_数据手册PDF_国产替代
pdf
asdzx673 天前
C# 操作 PDF 元数据:从属性写入到字段提取的完整流程
前端·pdf·c#
WORLDPO92263 天前
SFSDT-10/15/20/25/35-28-G-19.69-SR_实物图_数据手册PDF_国产替代
pdf·pcb工艺·pcb
梦想出海-Phoebe3 天前
Gemini新增文件编辑功能:PDF、Word、Excel处理体验分享
pdf·word·excel
开开心心就好3 天前
网页图片批量下载工具,输入链接就保存
服务器·算法·leetcode·支持向量机·pdf·ocr·1024程序员节
汤姆宝库4 天前
法考历年真题及答案解析合集pdf版(2002-2025年)
pdf·法考
优化控制仿真模型4 天前
2026【英一】考研英语一历年真题及答案解析PDF电子版(1980-2025年)
考研·pdf
云月呀5 天前
《死亡回忆录》藏汉双语版电子版 PDF,穆迪博士 150 例濒死体验访谈,一部关于生死的温柔读本
pdf·死亡回忆录
xiaolinudao1235 天前
给pdf文件盖骑缝章的软件有哪些
pdf