adai3474 发表于 2022-5-18 11:45

首贴 java PDF防水印去除思路

本帖最后由 adai3474 于 2022-5-20 16:32 编辑

来52四五年了 重来没发过贴
今天忙中偷闲 摸会鱼 分享个最近项目上遇到的需求和最终解决方案
客户需求是这样
文档上传后转pdf 在添加水印需求比较简单
后来发现这个水印可以通过市场上很多的pdf文档工具去除掉
甚至是一键去除 这下客户不满意了 觉得这个水印没用
好家伙 产品直接找到我 让我想办法优化
想了半天 第一个思路诞生
pdf加上编辑密码
ok 测试 通过
上线 通过
客户第二天又找来了
客户说下载了个pdf密码去除 秒破
{:1_890:}
静下心来思考一下
pdf解密这个我没法阻栏
那就重软件是怎么去除水印的入手
原来pdf水印就像ps图层一样 覆盖在最上层 如果彻底揉在一起呢 是不是解决了
那就 pdf转图片 图片在转pdf
ok
测试 通过
上线 通过
这下ok了 唯一的缺点就是 现在pdf放大会有像素块
全能扫码王等类似软件还是能去除 这个没办法
如果其他小伙伴有更好的办法 可以在交流!
下面分享一下代码
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

/**
* pdf转图片 在转pdf 防止pdf编辑
*/
public class pdftotp {
    /**
   * main方法
   */
    public static void main(String[] args) {
      String imgFolderPath = pdfToImage("C:\\Users\\Administrator\\Desktop\\1.pdf", "D:", 300);
      imageToPDF("D:",imgFolderPath);
    }


    /**
   * 保存到本地
   *
   * @Param imageFolderPath 图片文件夹地址
   * @param pdfPath         PDF文件保存地址
   */
    public static void toPdf(String imageFolderPath, String pdfPath) {
      //创建一个文档对象
      Document doc = new Document();
      try {
            // 输入流
            FileOutputStream fos = new FileOutputStream(pdfPath);
            // 写入PDF文档
            PdfWriter.getInstance(doc, fos);
            //开启文档
            doc.open();
            // 获取图片文件夹对象
            File file = new File(imageFolderPath);
            File[] files = file.listFiles();
            // 循环获取图片文件夹内的图片
            if (files != null && files.length > 0) {
                for (File f : files) {
                  if (f.getName().endsWith(".png")
                            || f.getName().endsWith(".jpg")
                            || f.getName().endsWith(".gif")
                            || f.getName().endsWith(".jpeg")
                            || f.getName().endsWith(".tif")) {
                        String imagePath = imageFolderPath + "\\" + f.getName();
                        // 实例化图片
                        Image image = Image.getInstance(imagePath);
                        //设置图片居中显示
                        image.setAlignment(Image.MIDDLE);
                        // 添加图片到文档
                        doc.add(image);
                        // 换行,增加间距
                        doc.add(new Paragraph("\n"));
                  }
                }
            }
            // 关闭文档
            doc.close();
      } catch (Exception e) {
            e.printStackTrace();
      }

    }


    /**
   * Description: <br>
   *
   * @param fileName   pdf文件路径
   * @param imagesPath 图片文件路径
   * @Return <br>
   * @AuThor <br>
   * @taskId <br>
   */

    public static File imageToPDF(String fileName, String imagesPath) {

      try {

// 生成14位消息流水号

            Random rand = new Random();

            String cardNnumer = "";

            for (int a = 0; a <= 14; a++) {

                cardNnumer += rand.nextInt(10);

            }

            fileName = fileName + "\\" + cardNnumer + ".pdf";

            File file = new File(fileName);

// 第一步:创建一个document对象。

            Document document = new Document(PageSize.A4, 0, 0, 0, 0);

// 第二步:

// 创建一个PdfWriter实例,

            PdfWriter.getInstance(document, new FileOutputStream(fileName));

// 第三步:打开文档。

            document.open();

// 第四步:在文档中增加图片。

            File files = new File(imagesPath);

            String[] images = files.list();

            int len = images.length;


            for (int i = 0; i < len; i++) {

                if (images.toLowerCase().endsWith(".bmp")

                        || images.toLowerCase().endsWith(".jpg")

                        || images.toLowerCase().endsWith(".jpeg")

                        || images.toLowerCase().endsWith(".gif")

                        || images.toLowerCase().endsWith(".png")) {

                  String temp = imagesPath + "\\" + images;

                  Image img = Image.getInstance(temp);

                  img.setAlignment(Image.ALIGN_CENTER);

// 根据图片大小设置页面,一定要先设置页面,再newPage(),否则无效

                  document.setPageSize(new Rectangle(img.getWidth(), img.getHeight()));

                  document.newPage();

                  document.add(img);

                }

            }

// 第五步:关闭文档。

            document.close();

            return file;

      } catch (Exception e) {

// TODO Auto-generated catch block

            e.printStackTrace();

            return null;

      }

    }


    /**
   * PDF文件转PNG图片,全部页数
   *
   * @param PdfFilePathpdf完整路径
   * @param dstImgFolder 图片存放的文件夹
   * @param dpi          dpi越大转换后越清晰,相对转换速度越慢
   * @return 返回转换后图片集合list
   */
    public static String pdfToImage(String PdfFilePath, String dstImgFolder, int dpi) {
      UUID uuid = UUID.randomUUID();
      String uuId = uuid.toString();
      System.out.println(uuId);
      File file = new File(PdfFilePath);
      //定义集合保存返回图片数据
      List<File> fileList = new ArrayList<File>();
      @SuppressWarnings("resource")//抑制警告
      PDDocument pdDocument = new PDDocument();
      try {
            //String imagePDFName = file.getName().substring(0, dot); // 获取图片文件名
            String imgFolderPath = null;
            if (dstImgFolder.equals("")) {
                imgFolderPath = dstImgFolder + File.separator + uuId;// 获取图片存放的文件夹路径
            } else {
                imgFolderPath = dstImgFolder + File.separator + uuId;
            }
            if (createDirectory(imgFolderPath)) {
                pdDocument = PDDocument.load(file);
                PDFRenderer renderer = new PDFRenderer(pdDocument);
                /* dpi越大转换后越清晰,相对转换速度越慢 */
                PdfReader reader = new PdfReader(PdfFilePath);
                int pages = reader.getNumberOfPages();
                System.out.println("pdf总共多少页-----" + pages);
                StringBuffer imgFilePath = null;
                for (int i = 0; i < pages; i++) {
                  String imgFilePathPrefix = imgFolderPath + File.separator + "study";
                  System.out.println("imgFilePathPrefix=====" + imgFilePathPrefix);
                  imgFilePath = new StringBuffer();
                  imgFilePath.append(imgFilePathPrefix);
                  imgFilePath.append("-");
                  imgFilePath.append(String.valueOf(i));
                  imgFilePath.append(".jpg");
                  File dstFile = new File(imgFilePath.toString());
                  BufferedImage image = renderer.renderImageWithDPI(i, dpi);
                  ImageIO.write(image, "png", dstFile);
                  fileList.add(dstFile);
                }
                System.out.println("PDF文档转PNG图片成功!");
                return imgFolderPath;
            } else {
                System.out.println("PDF文档转PNG图片失败:" + "创建" + imgFolderPath + "失败");
                return null;
            }
      } catch (IOException e) {
            e.printStackTrace();
            return null;
      }
    }

    //创建文件夹
    private static boolean createDirectory(String folder) {
      File dir = new File(folder);
      if (dir.exists()) {
            return true;
      } else {
            return dir.mkdirs();
      }
    }

    //删除文件夹
    //param folderPath 文件夹完整绝对路径
    public static void delFolder(String folderPath) {
      try {
            delAllFile(folderPath); //删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); //删除空文件夹
      } catch (Exception e) {
            e.printStackTrace();
      }
    }

    //删除指定文件夹下所有文件
    //param path 文件夹完整绝对路径
    public static boolean delAllFile(String path) {
      boolean flag = false;
      File file = new File(path);
      if (!file.exists()) {
            return flag;
      }
      if (!file.isDirectory()) {
            return flag;
      }
      String[] tempList = file.list();
      File temp = null;
      for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList);
            } else {
                temp = new File(path + File.separator + tempList);
            }
            if (temp.isFile()) {
                temp.delete();

            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList);//先删除文件夹里面的文件
                delFolder(path + "/" + tempList);//再删除空文件夹
                flag = true;
            }
      }
      return flag;
    }

}


32K 发表于 2022-5-18 13:16

adai3474 发表于 2022-5-18 12:28
可以分享一下去除的工具或者思路嘛

那种“魔术去水印”,通过学习算法推测还原出被水印覆盖地方原先的样子,不过有时(很大几率)会不自然,论坛里好像有分享这种工具的

adai3474 发表于 2022-5-18 13:35

32K 发表于 2022-5-18 13:16
那种“魔术去水印”,通过学习算法推测还原出被水印覆盖地方原先的样子,不过有时(很大几率)会不自然, ...

哦哦 这种是没办法 全能扫描王就可以 我觉得最高只能做到这个程度了

cszdz999 发表于 2022-5-18 12:11

本帖最后由 cszdz999 于 2022-5-19 20:50 编辑

高手编程。

adai3474 发表于 2022-5-18 12:28

cszdz999 发表于 2022-5-18 12:11
一样可去水印!

可以分享一下去除的工具或者思路嘛

永恒陌 发表于 2022-5-18 13:54

水印弄成跟文档颜色一致的,然后贴图片里,就能防止那些通过颜色去除水印的工具了。

cs5282683 发表于 2022-5-18 13:58

看看好东西

云在天 发表于 2022-5-18 14:14

永恒陌 发表于 2022-5-18 13:54
水印弄成跟文档颜色一致的,然后贴图片里,就能防止那些通过颜色去除水印的工具了。

水印不能影响显示效果,不然就没有意义了

永恒陌 发表于 2022-5-18 14:21

云在天 发表于 2022-5-18 14:14
水印不能影响显示效果,不然就没有意义了

那就水印弄成多色渐变那种,哈哈哈哈哈

deepgo 发表于 2022-5-18 14:48

说说思路呗
页: [1] 2 3
查看完整版本: 首贴 java PDF防水印去除思路