使用python去除PDF简单水印的示例
前言
最近在下载PDF书籍的时候,发现有些PDF有水印,于是就寻思着能不能用Python去除这些讨厌的水印
一、PDF文件
关于PDF文件,想必大家都很熟悉了,这里就不过多的介绍了。PDF主要有两种类型,一种是文字版,另外一种就是扫描版(图片)。这个去除水印主要就是针对扫描版的PDF
二、思路整理
在开始写代码之前,先捋一下实现的思路
1、分割图片
对于一个PDF文件,我们只需要图片信息就可以了,所以首先需要先提取里边的图片,再把图片存在一个目录下。这里需要用到fitz模块,直接安装即可,如下:
模块安装完之后,代码就很简单了,只需要注意一下图片按顺序命名即可,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def split_pdf(file_path, out_path): """ 切割pdf为图片 :param file_path: pdf路径 :param out_path: 输出图片路径 :return: 输出路径 """ pdf = fitz. open (file_path) count = 0 print ( "##### 开始保存切割图片 #####" ) for page in pdf: image_list = page.get_images() for img_info in image_list: pix = fitz.Pixmap(pdf, img_info[ 0 ]) pix.save(os.path.join(out_path, '%d.jpg' % count)) count + = 1 print ( "##### 保存切割图片完毕 #####" ) print ( "##### {0} 包含 {1} 张图片 #####" . format (file_path, count)) return out_path |
2、去除水印
分割完图片后,接下来的问题也随之而来了,要如何区分水印和正常图片? 要替换成什么? 先来看第一个问题,如何区分水印
- 按水印位置
这个问题,最直观的想法就是根据水印的位置以及水印的大小,进行替换就可以。但是这样存在问题,首先就是不通用(PDF水印的位置可能不一样),再者就是水印和字混在一起就不好弄了
像这种水印,坐标和大小是可以去除的
像这种字和水印混在一起就难办了
- 按颜色
我们在观察下水印,发现水印的颜色一般偏亮一点,而字都是偏暗色的(黑色、灰色)。我们可以根据颜色将亮一点的颜色都替换掉。但这种方式也有问题,如果是彩色的,就够呛了
对于第二个问题:要替换成什么? 如果只有简单的颜色(黑白灰等),我们直接把水印替换成白色即可
接下来来看下代码吧,这里需要用到PIL模块,直接安装就行了,如下:
思路有了,代码就简单了,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | def get_image_arr(img): """ 获取图片三色数组 :param img:图片 :return: 图片编码、三色数组 """ img_arr = np.asarray(img, dtype = np.double) # 分离通道 r_img = img_arr[:, :, 0 ].copy() g_img = img_arr[:, :, 1 ].copy() b_img = img_arr[:, :, 2 ].copy() img = r_img * 256 * 256 + g_img * 256 + b_img return img, r_img, g_img, b_img def replace_clr_color(img, src_clr, dst_clr): """ 通过矩阵操作颜色替换程序 @param img: 图像矩阵 @param src_clr: 需要替换的颜色(r,g,b) @param dst_clr: 目标颜色 (r,g,b) @return 替换后的图像矩阵 """ img, r_img, g_img, b_img = get_image_arr(img) src_color = src_clr[ 0 ] * 256 * 256 + src_clr[ 1 ] * 256 + src_clr[ 2 ] # 索引并替换颜色 r_img[img = = src_color] = dst_clr[ 0 ] g_img[img = = src_color] = dst_clr[ 1 ] b_img[img = = src_color] = dst_clr[ 2 ] return compound_img(r_img, g_img, b_img) def compound_img(r_img, g_img, b_img): """ 合并图片 :param r_img: 红色 :param g_img: 绿色 :param b_img: 蓝色 :return: 图片 """ # 合并通道 dst_img = np.array([r_img, g_img, b_img], dtype = np.uint8) # 将数据转换为图像数据(h,w,c) dst_img = dst_img.transpose( 1 , 2 , 0 ) return dst_img def replace_pure_color(img, src_color, dst_color): """ 通过矩阵操作颜色替换程序(纯色) :param img: 图像矩阵 :param src_color: 需要替换的颜色 :param dst_color: 目标颜色 :return: 图片 """ img, r_img, g_img, b_img = get_image_arr(img) src_color = src_color * 256 * 256 + src_color * 256 + src_color # 索引并替换颜色 r_img[img > = src_color] = dst_color g_img[img > = src_color] = dst_color b_img[img > = src_color] = dst_color return compound_img(r_img, g_img, b_img) def wipe_watermark(img_file, start_color): """ 去除图片水印 :param start_color: 颜色起始替换位置 :param img_file: 图片文件 :return: """ img = replace_pure_color(Image. open (img_file).convert( 'RGB' ), start_color, 255 ) res_img = Image.fromarray(img) res_img.save(img_file) |
3、替换图片
保存完去除水印后的图片,接下来只要把他一个个替换进去就行了
由于原始PDF文件可以有其他东西(书签等),所以我们先把原始文件读取进去,在进行替换,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def save_pdf(src_pdf, dest_pdf, file_list): """ 生成最终pdf文件 :param src_pdf: 源文件 :param dest_pdf: 目标文件 :param file_list: 图片列表 :return: """ pdf = fitz. open (src_pdf) index = 0 try : for page in pdf: # 去除超链接 for link in page.get_links(): page.delete_link(link) # 替换图片 for img in page.get_images(): page._insert_image(filename = file_list[index], _imgname = img[ 7 ]) index = index + 1 pdf.save(dest_pdf) finally : pdf.close() |
三、实现效果
lu完代码,再来看一下效果怎么样,这边用了两个PDF做实验,第一个PDF效果如下:
去除水印前:
去除水印后:
第二个PDF效果如下:
去除水印前:
去除水印后:
感觉效果还阔以,哈哈。不过这里有个问题,对于文字logo,查了PyMuPDF文档没找到罒ω罒,像这种
四、代码实现
全部代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | import os import fitz import numpy as np from PIL import Image def split_pdf(file_path, out_path): """ 切割pdf为图片 :param file_path: pdf路径 :param out_path: 输出图片路径 :return: 输出路径 """ pdf = fitz. open (file_path) count = 0 print ( "##### 开始保存切割图片 #####" ) for page in pdf: image_list = page.get_images() for img_info in image_list: pix = fitz.Pixmap(pdf, img_info[ 0 ]) pix.save(os.path.join(out_path, '%d.jpg' % count)) count + = 1 print ( "##### 保存切割图片完毕 #####" ) print ( "##### {0} 包含 {1} 张图片 #####" . format (file_path, count)) return out_path def get_image_arr(img): """ 获取图片三色数组 :param img:图片 :return: 图片编码、三色数组 """ img_arr = np.asarray(img, dtype = np.double) # 分离通道 r_img = img_arr[:, :, 0 ].copy() g_img = img_arr[:, :, 1 ].copy() b_img = img_arr[:, :, 2 ].copy() img = r_img * 256 * 256 + g_img * 256 + b_img return img, r_img, g_img, b_img def replace_clr_color(img, src_clr, dst_clr): """ 通过矩阵操作颜色替换程序 @param img: 图像矩阵 @param src_clr: 需要替换的颜色(r,g,b) @param dst_clr: 目标颜色 (r,g,b) @return 替换后的图像矩阵 """ img, r_img, g_img, b_img = get_image_arr(img) src_color = src_clr[ 0 ] * 256 * 256 + src_clr[ 1 ] * 256 + src_clr[ 2 ] # 索引并替换颜色 r_img[img = = src_color] = dst_clr[ 0 ] g_img[img = = src_color] = dst_clr[ 1 ] b_img[img = = src_color] = dst_clr[ 2 ] return compound_img(r_img, g_img, b_img) def compound_img(r_img, g_img, b_img): """ 合并图片 :param r_img: 红色 :param g_img: 绿色 :param b_img: 蓝色 :return: 图片 """ # 合并通道 dst_img = np.array([r_img, g_img, b_img], dtype = np.uint8) # 将数据转换为图像数据(h,w,c) dst_img = dst_img.transpose( 1 , 2 , 0 ) return dst_img def replace_pure_color(img, src_color, dst_color): """ 通过矩阵操作颜色替换程序(纯色) :param img: 图像矩阵 :param src_color: 需要替换的颜色 :param dst_color: 目标颜色 :return: 图片 """ img, r_img, g_img, b_img = get_image_arr(img) src_color = src_color * 256 * 256 + src_color * 256 + src_color # 索引并替换颜色 r_img[img > = src_color] = dst_color g_img[img > = src_color] = dst_color b_img[img > = src_color] = dst_color return compound_img(r_img, g_img, b_img) def list_file(path, suffix = None ): """ 获取指定目录下指定后缀文件 :param path: 路径 :param suffix: 后缀名 :return: 文件集合 """ file_names = os.listdir(path); # 获取文件名 if suffix is not None : file_names = [file_name for file_name in file_names if file_name.endswith(suffix)] file_names.sort(key = lambda x: int (x[:( - len (suffix))])) # 文件名拼接路径 return [os.path.join(path, file ) for file in file_names] def wipe_watermark(img_file, start_color): """ 去除图片水印 :param start_color: 颜色起始替换位置 :param img_file: 图片文件 :return: """ img = replace_pure_color(Image. open (img_file).convert( 'RGB' ), start_color, 255 ) res_img = Image.fromarray(img) res_img.save(img_file) def save_pdf(src_pdf, dest_pdf, file_list): """ 生成最终pdf文件 :param src_pdf: 源文件 :param dest_pdf: 目标文件 :param file_list: 图片列表 :return: """ pdf = fitz. open (src_pdf) index = 0 try : for page in pdf: # 去除超链接 for link in page.get_links(): page.delete_link(link) # 替换图片 for img in page.get_images(): page._insert_image(filename = file_list[index], _imgname = img[ 7 ]) index = index + 1 pdf.save(dest_pdf) finally : pdf.close() def start(file_path, dest_path, start_color, out_path = r 'out' ): if os.path.exists(out_path): # shutil.rmtree(out_path) raise FileExistsError( '文件夹:{0} 已存在' . format (out_path)) os.mkdir(out_path) print ( "####### 开始切割pdf:{0} #######" . format (file_path)) split_pdf(file_path, out_path) print ( "####### 切割pdf完毕:{0} #######" . format (file_path)) # 获取文件名 file_list = list_file(out_path, ".jpg" ) print ( "####### 开始去除水印 #######" ) for img_file in file_list: wipe_watermark(img_file, start_color) print ( "####### 去除水印结束 #######" ) # 生成pdf print ( "####### 生成pdf文件:{0} #######" . format (dest_path)) save_pdf(src_pdf = file_path, dest_pdf = dest_path, file_list = file_list) print ( "####### 生成pdf文件:{0} 完成 #######" . format (dest_path)) # make_pdf(dest_path, file_list) if __name__ = = '__main__' : # replace_pdf(src_pdf="深入剖析TOMCAT.pdf", dest_pdf='a.pdf', file_list=list_file('out', ".jpg")) # www.TopSage.com start(file_path = "重构-改善既有代码的设计.pdf" , dest_path = "b.pdf" , start_color = 175 ) |
总结
这里实现相对比较简单,只能去除一些纯色图片的PDF。
以上就是使用python去除PDF简单水印的示例的详细内容,更多关于python去除PDF水印的资料请关注脚本之家其它相关文章!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
Python Django 添加首页尾页上一页下一页代码实例
这篇文章主要介绍了Python Django 添加首页尾页上一页下一页代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2019-08-08
最新评论