使用python去除PDF簡單水印的示例
前言
最近在下載PDF書籍的時候,發(fā)現(xiàn)有些PDF有水印,于是就尋思著能不能用Python去除這些討厭的水印
一、PDF文件
關于PDF文件,想必大家都很熟悉了,這里就不過多的介紹了。PDF主要有兩種類型,一種是文字版,另外一種就是掃描版(圖片)。這個去除水印主要就是針對掃描版的PDF
二、思路整理
在開始寫代碼之前,先捋一下實現(xiàn)的思路
1、分割圖片
對于一個PDF文件,我們只需要圖片信息就可以了,所以首先需要先提取里邊的圖片,再把圖片存在一個目錄下。這里需要用到fitz模塊,直接安裝即可,如下:
pip install PyMuPDF
模塊安裝完之后,代碼就很簡單了,只需要注意一下圖片按順序命名即可,如下:
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、去除水印
分割完圖片后,接下來的問題也隨之而來了,要如何區(qū)分水印和正常圖片? 要替換成什么? 先來看第一個問題,如何區(qū)分水印
- 按水印位置
這個問題,最直觀的想法就是根據(jù)水印的位置以及水印的大小,進行替換就可以。但是這樣存在問題,首先就是不通用(PDF水印的位置可能不一樣),再者就是水印和字混在一起就不好弄了
像這種水印,坐標和大小是可以去除的
像這種字和水印混在一起就難辦了
- 按顏色
我們在觀察下水印,發(fā)現(xiàn)水印的顏色一般偏亮一點,而字都是偏暗色的(黑色、灰色)。我們可以根據(jù)顏色將亮一點的顏色都替換掉。但這種方式也有問題,如果是彩色的,就夠嗆了
對于第二個問題:要替換成什么? 如果只有簡單的顏色(黑白灰等),我們直接把水印替換成白色即可
接下來來看下代碼吧,這里需要用到PIL模塊,直接安裝就行了,如下:
pip install pillow
思路有了,代碼就簡單了,如下:
def get_image_arr(img): """ 獲取圖片三色數(shù)組 :param img:圖片 :return: 圖片編碼、三色數(shù)組 """ 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) # 將數(shù)據(jù)轉換為圖像數(shù)據(jù)(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文件可以有其他東西(書簽等),所以我們先把原始文件讀取進去,在進行替換,代碼如下:
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()
三、實現(xiàn)效果
lu完代碼,再來看一下效果怎么樣,這邊用了兩個PDF做實驗,第一個PDF效果如下:
去除水印前:
去除水印后:
第二個PDF效果如下:
去除水印前:
去除水印后:
感覺效果還闊以,哈哈。不過這里有個問題,對于文字logo,查了PyMuPDF文檔沒找到罒ω罒,像這種
四、代碼實現(xiàn)
全部代碼如下:
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): """ 獲取圖片三色數(shù)組 :param img:圖片 :return: 圖片編碼、三色數(shù)組 """ 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) # 將數(shù)據(jù)轉換為圖像數(shù)據(jù)(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)
總結
這里實現(xiàn)相對比較簡單,只能去除一些純色圖片的PDF。
以上就是使用python去除PDF簡單水印的示例的詳細內容,更多關于python去除PDF水印的資料請關注腳本之家其它相關文章!
相關文章
python matplotlib繪圖實現(xiàn)刪除重復冗余圖例的操作
這篇文章主要介紹了python matplotlib繪圖實現(xiàn)刪除重復冗余圖例的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04使用TensorFlow創(chuàng)建生成式對抗網絡GAN案例
這篇文章主要為大家介紹了使用TensorFlow創(chuàng)建生成式對抗網絡GAN案例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Python利用Selenium實現(xiàn)自動觀看學習通視頻
Selenium是一個用于Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。本文主要介紹了利用Selenium實現(xiàn)自動觀看學習通視頻,需要的同學可以參考一下2021-12-12python操作mysql實現(xiàn)一個超市管理系統(tǒng)
超市管理系統(tǒng)有管理員和普通用戶兩條分支,只需掌握Python基礎語法,就可以完成這個項目,下面這篇文章主要給大家介紹了關于python操作mysql實現(xiàn)一個超市管理系統(tǒng)的相關資料,需要的朋友可以參考下2022-12-12Python替換Excel表格中的空值或指定值的實現(xiàn)
本文介紹了使用Python的pandas庫結合openpyxl來批量替換Excel表格中的空值或指定值,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-12-12