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

 更新时间:2022年11月14日 10:37:21   作者:初窥门径  
有时候需要给pdf加水印,市面上工具都是收费的要会员,还是自食其力吧;尝试过 spire.pdf.free 那个超过10页就不行了!所以本文还是使用了pdfbox,感兴趣的可以了解一下

引入依赖

<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添加图片水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中连接数据库方式详细步骤记录

    Java中连接数据库方式详细步骤记录

    这篇文章主要介绍了Java中连接数据库方式的详细步骤,包括添加依赖、建立连接、执行SQL语句、处理结果集和关闭连接,还讨论了数据库连接池的使用,需要的朋友可以参考下
    2025-01-01
  • AspectJ的基本用法

    AspectJ的基本用法

    本文主要介绍了AspectJ的基本用法。具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • spring Security的自定义用户认证过程详解

    spring Security的自定义用户认证过程详解

    这篇文章主要介绍了spring Security的自定义用户认证过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java语言之包和继承详解

    Java语言之包和继承详解

    这篇文章主要介绍了java的包和继承,结合实例形式详细分析了Java继承的概念、原理、用法及相关操作注意事项,需要的朋友可以参考下
    2021-09-09
  • java实现幸运抽奖功能

    java实现幸运抽奖功能

    这篇文章主要为大家详细介绍了java实现幸运抽奖功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Spring容器中已经存在的Bean替换示例

    Spring容器中已经存在的Bean替换示例

    这篇文章主要为大家介绍了Spring容器中已经存在的Bean替换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Spring MVC 中拦截器的使用示例详解"拦截器基本配置"和 "拦截器高级配置"

    Spring MVC 中拦截器的使用示例详解"拦截器基本配置"和 &q

    Spring MVC 的拦截器作用是在请求到达控制器之前或之后进行拦截,可以对请求和响应进行一些特定的处理,这篇文章主要介绍了Spring MVC 中的拦截器的使用“拦截器基本配置” 和 “拦截器高级配置”,需要的朋友可以参考下
    2024-07-07
  • Maven中的SnapShot版本和正式版本的区别

    Maven中的SnapShot版本和正式版本的区别

    在Nexus仓库中,一个仓库一般分为public(Release)仓和SNAPSHOT仓,本文详细的介绍了SnapShot版本和正式版本的区别,感兴趣的可以了解一下
    2021-06-06
  • 基于jfreechart生成曲线、柱状等图片并展示到JSP

    基于jfreechart生成曲线、柱状等图片并展示到JSP

    这篇文章主要介绍了基于jfreechart生成曲线、柱状等图片并展示到JSP,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • mybatis升级mybatis-plus时踩到的一些坑

    mybatis升级mybatis-plus时踩到的一些坑

    这篇文章主要给大家介绍了关于mybatis升级mybatis-plus时踩到的一些坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论