文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java使用pdfbox实现给pdf文件加图片水印

2022-11-16 00:15

关注

引入依赖

<dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.27</version>
        </dependency>

代码

调节参数:图片宽高,旋转角度,几行几列 等等

package sjp.demo.workutils.utils;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.blend.BlendMode;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

import java.io.File;
import java.io.IOException;

public class PdfUtils {

    public static void main(String[] args) throws IOException {
        String file = "D:\\workspaces\\demo\\sjp-work-utils\\src\\main\\resources\\pdf\\阿拉丁统计平台SDK接入指南.pdf";
        String imgPath = "D:\\workspaces\\demo\\sjp-work-utils\\src\\main\\resources\\imgs\\logo.png";
        addImgWatermark(file, imgPath);

    }

    public static void addImgWatermark(String filePath, String imgPath) throws IOException {
        String name = filePath.substring(filePath.lastIndexOf(File.separator), filePath.lastIndexOf(".pdf"));
        String folder = filePath.substring(0, filePath.lastIndexOf(File.separator));
        File file = new File(filePath);
        try (PDDocument doc = PDDocument.load(file)) {
            PDImageXObject pdImage = PDImageXObject.createFromFile(imgPath, doc);

            WatermarkOptions options = new WatermarkOptions()
                    .size(120, 60)
                    .padding(20)
                    .layout(4, 3)
                    // 建议0-90度
                    .rotate(30);

            for (PDPage page : doc.getPages()) {
                addImgWatermark(doc, page, pdImage, options);
            }
            doc.save(folder + File.separator + name + "_WaterMark.pdf");
        }

    }

    private static void addImgWatermark(PDDocument doc, PDPage page, PDImageXObject pdImage, WatermarkOptions options) throws IOException {
        try (
                PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true)
        ) {
            float width = page.getMediaBox().getWidth();
            float height = page.getMediaBox().getHeight();
//            System.out.println("width=" + width + ",height=" + height);

            //有一些pdf页面是有角度翻转的,修正一下
            int rotation = page.getRotation();
//            System.out.println("page.getRotation()=" + rotation);
            switch (rotation) {
                case 90:
                    width = page.getMediaBox().getHeight();
                    height = page.getMediaBox().getWidth();
                    cs.transform(Matrix.getRotateInstance(Math.toRadians(90), height, 0));
                    break;
                case 180:
                    cs.transform(Matrix.getRotateInstance(Math.toRadians(180), width, height));
                    break;
                case 270:
                    width = page.getMediaBox().getHeight();
                    height = page.getMediaBox().getWidth();
                    cs.transform(Matrix.getRotateInstance(Math.toRadians(270), 0, width));
                    break;
                default:
                    break;
            }

            PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
            gs.setNonStrokingAlphaConstant(0.2f);// 设置透明度
            gs.setAlphaSourceFlag(true);
            gs.setBlendMode(BlendMode.NORMAL);
            cs.setGraphicsStateParameters(gs);

            int row = options.row;
            int column = options.column;
            float imgWidth = options.width;
            float imgHeight = options.height;
            float padding = options.padding;
            int degree = options.degree;

            // 计算获得每个单元格的宽高
            float cellWidth = (width - padding * 2) / column;
            float cellHeight = (height - padding * 2) / row;
//            System.out.println("cellWidth=" + cellWidth + ",cellHeight=" + cellHeight);

            // 偏移量,如果单元格宽高大于图片宽高,这可以使图片居中
            float xOffset = padding + (cellWidth - imgWidth) / 2;
            float yOffset = padding + (cellHeight - imgHeight) / 2;

            float x;
            float y;
            for (int i = 0; i < row; i++) {
                y = i * cellHeight + yOffset; 

                for (int j = 0; j < column; j++) {
                    x = j * cellWidth + xOffset;

                    // 旋转导致的x位置修正
                    x += Math.sin(Math.toRadians(degree)) * imgHeight;

//                    System.out.println((int) x + "," + (int) y);

                    Matrix matrix = new Matrix();
                    // 先移位
                    matrix.translate(x, y);
                    // 旋转
                    matrix.rotate(Math.toRadians(degree));
                    // 修改尺寸(必须在旋转后面,否则会变形)
                    matrix.scale(imgWidth, imgHeight);

                    // 画图
                    cs.drawImage(pdImage, matrix);
                }
            }

        }

    }

    static class WatermarkOptions {
        
        float padding = 20;
        
        float width;
        
        float height;
        
        int degree = 0;
        
        int row = 1;
        
        int column = 1;

        public WatermarkOptions() {

        }

        public WatermarkOptions padding(int p) {
            if (p < 10) {
                throw new IllegalArgumentException("边距不能小于0");
            }
            this.padding = p;
            return this;
        }

        public WatermarkOptions layout(int row, int column) {
            if (row <= 0 || column <= 0) {
                throw new IllegalArgumentException("行数或列数必须大于0");
            }
            this.row = row;
            this.column = column;

            return this;
        }

        public WatermarkOptions size(float width, float height) {
            this.width = width;
            this.height = height;
            return this;
        }

        public WatermarkOptions rotate(int degree) {
            this.degree = degree;
            return this;
        }

    }

}

效果

到此这篇关于Java使用pdfbox实现给pdf文件加图片水印的文章就介绍到这了,更多相关Java pdfbox添加图片水印内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯