弟弟最近要考試,臨時抱佛腳在網上找了一堆學習資料複習,這不剛就來找我了,說PDF上有水印,影響閱讀效果,到時候考不好就怪資料不行,氣的我差點當場想把他揍一頓! 算了,弟弟長大了,看在打不過他的份上,就不打他了~ 稍加思索,我想起了Python不是可以去水印?說搞就搞! 去除水印原理 去除方法: 用 ...
弟弟最近要考試,臨時抱佛腳在網上找了一堆學習資料複習,這不剛就來找我了,說PDF上有水印,影響閱讀效果,到時候考不好就怪資料不行,氣的我差點當場想把他揍一頓!
算了,弟弟長大了,看在打不過他的份上,就不打他了~
稍加思索,我想起了Python不是可以去水印?說搞就搞!
去除水印原理
去除方法:
- 用 PyMuPDF 打開 pdf 文件,將 pdf 的每一頁都轉換為圖片 pixmap
- pixmap 有它自己的RGB,只需要將 pdf 水印中的 RGB 改為(255, 255, 255),並保存圖片 ;
- 按照生成的圖片,插入到pdf文檔中;
因為pfd文檔無法直接去除水印,需要先將pfd文檔轉換成圖片,在逐一對圖片進行水印去除操作,最後在把圖片插入到pdf文檔中。
代碼剖析
1、先查看PDF文檔中的水印rgb值是多少
可以看到,RGB(179,179,179),因為這裡要的是RGB色值總和,所以我們就認為,超過510,就認為是水印。
敲黑板
光學三原色是紅綠藍(RGB),也就是說它們是不可分解的三種基本顏色,其他顏色都可以通過這三種顏色混合而成,三種顏色等比例混合就是白色,沒有光就是黑色。
在電腦中,可以用三個位元組表示 RGB 顏色,1個位元組能表示的最大數值是 255, 所以,(255, 0, 0)代表紅色,(0, 255, 0)代表綠色,(0, 0, 255)代表藍色。相應地,(255, 255, 255)代表白色,(0, 0, 0)代表黑色。從(0, 0, 0) ~ (255, 255, 255) 之間的任意組合都可以代表一個不同的顏色。
圖片每個位置顏色由四元組表示,前三位分別是 RGB,第四位是 Alpha 通道。
2、pdf轉換成圖片,並去除水印
代碼示例:
from PIL import Image from itertools import product import fitz # Python學習交流群:708525271 # 去除pdf的水印 def remove_pdfwatermark(): #打開源pfd文件 pdf_file = fitz.open("源碼找落落阿.pdf") #page_no 設置為0 page_no = 0 #page在pdf文件中遍歷 for page in pdf_file: #獲取每一頁對應的圖片pix (pix對象類似於我們上面看到的img對象,可以讀取、修改它的 RGB) #page.get_pixmap() 這個操作是不可逆的,即能夠實現從 PDF 到圖片的轉換,但修改圖片 RGB 後無法應用到 PDF 上,只能輸出為圖片 pix = page.get_pixmap() #遍歷圖片中的寬和高,如果像素的rgb值總和大於510,就認為是水印,轉換成255,255,255-->即白色 for pos in product(range(pix.width), range(pix.height)): if sum(pix.pixel(pos[0], pos[1])) >= 510: pix.set_pixel(pos[0], pos[1], (255, 255, 255)) #保存去掉水印的截圖 pix.pil_save(f"./{page_no}.png", dpi=(30000, 30000)) #列印結果 print(f'第 {page_no} 頁去除完成') page_no += 1 if __name__ == '__main__': remove_pdfwatermark()
執行完成
查看生成圖片:
查看圖片內容
3、圖片轉為pdf
代碼示例:
from PIL import Image from itertools import product import fitz ''' 圖片轉為pdf''' #圖片所在的文件夾 pic_dir = 'F:\123' pdf = fitz.open() #圖片數字文件先轉換成int類型進行排序 img_files = sorted(os.listdir(pic_dir), key=lambda x: int(str(x).split('.')[0])) for img in img_files: print(img) imgdoc = fitz.open(pic_dir + '/' + img) #將打開後的圖片轉成單頁pdf pdfbytes = imgdoc.convertToPDF() imgpdf = fitz.open("pdf", pdfbytes) #將單頁pdf插入到新的pdf文檔中 pdf.insertPDF(imgpdf) pdf.save("源碼找落落阿_完成.pdf") pdf.close()
執行代碼
查看生成的pdf文檔
代碼整合
上面的內容都瞭解以後,我們就整合代碼,直接運行就可以了。
from PIL import Image from itertools import product import fitz # 去除pdf的水印 def remove_pdfwatermark(): # 打開源pfd文件 pdf_file = fitz.open("源碼找落落阿.pdf") # page_no 設置為0 page_no = 0 # page在pdf文件中遍歷 for page in pdf_file: # 獲取每一頁對應的圖片pix (pix對象類似於我們上面看到的img對象,可以讀取、修改它的 RGB) # page.get_pixmap() 這個操作是不可逆的,即能夠實現從 PDF 到圖片的轉換,但修改圖片 RGB 後無法應用到 PDF 上,只能輸出為圖片 pix = page.get_pixmap() # 遍歷圖片中的寬和高,如果像素的rgb值總和大於510,就認為是水印,轉換成255,255,255-->即白色 for pos in product(range(pix.width), range(pix.height)): if sum(pix.pixel(pos[0], pos[1])) >= 510: pix.set_pixel(pos[0], pos[1], (255, 255, 255)) # 保存去掉水印的截圖 pix.pil_save(f"./{page_no}.png", dpi=(30000, 30000)) # 列印結果 print(f'第 {page_no} 頁去除完成') page_no += 1 # 去除的pdf水印添加到pdf文件中 def pictopdf(): # 水印截圖所在的文件夾 # pic_dir = input("請輸入圖片文件夾路徑:") pic_dir = 'F:\123' pdf = fitz.open() # 圖片數字文件先轉換成int類型進行排序 img_files = sorted(os.listdir(pic_dir), key=lambda x: int(str(x).split('.')[0])) for img in img_files: print(img) imgdoc = fitz.open(pic_dir + '/' + img) # 將打開後的圖片轉成單頁pdf pdfbytes = imgdoc.convertToPDF() imgpdf = fitz.open("pdf", pdfbytes) # 將單頁pdf插入到新的pdf文檔中 pdf.insertPDF(imgpdf) pdf.save("源碼找落落阿_完成.pdf") pdf.close() if __name__ == '__main__': remove_pdfwatermark() pictopdf() # 兄弟們學習python,有時候不知道怎麼學,從哪裡開始學。掌握了基本的一些語法或者做了兩個案例後,不知道下一步怎麼走,不知道如何去學習更加高深的知識。 # 那麼對於這些大兄弟們,我準備了大量的免費視頻教程,PDF電子書籍,以及源代碼! # 直接在這個摳裙 708525271 自取即可~
總結
需要理解的流程是:
- pdf文檔需要先轉換成圖片,進行水印去除;
- 再轉換成pdf ;
- 最後插入到新的pdf文檔中;
寫到這裡,今天的分享就差不多快結束了,咱們下次再見!