Python去除PDF水印的實(shí)現(xiàn)示例
今天介紹下用 Python 去除 PDF (圖片)的水印。思路很簡單,代碼也很簡潔。
首先來考慮 Python 如何去除圖片的水印,然后再將思路復(fù)用到 PDF 上面。
這張圖片是前幾天整理《數(shù)據(jù)結(jié)構(gòu)和算法》PDF里的一個(gè)截圖,帶著公眾號的水印。
從上圖可以明顯看到,為了不影響閱讀正文,水印顏色一般比較淺。因此,我們可以利用顏色差這個(gè)特征來去掉水印。即:用 Python 讀取圖片的顏色,并將淺顏色部分變白。
Python 標(biāo)準(zhǔn)庫 PIL 可以獲取圖片的顏色,Python2 是系統(tǒng)自帶的,Python3 需要自己安裝,我用的 Python 3.8,需要執(zhí)行以下
命令安裝
pip install pillow
安裝完成,讀取圖片,并獲取圖片的尺寸(寬度和高度)
from PIL import Image img = Image.open('watermark_pic.png') width, height = img.size
進(jìn)行下一步之前,先簡單介紹下計(jì)算機(jī)里關(guān)于顏色的知識。光學(xué)三原色是紅綠藍(lán)(RGB),也就是說它們是不可分解的三種基本顏色,其他顏色都可以通過這三種顏色混合而成,三種顏色等比例混合就是白色,沒有光就是黑色。
在計(jì)算機(jī)中,可以用三個(gè)字節(jié)表示 RGB 顏色,1個(gè)字節(jié)能表示的最大數(shù)值是 255, 所以,(255, 0, 0)代表紅色,(0, 255, 0)代表綠色,(0, 0, 255)代表藍(lán)色。相應(yīng)地,(255, 255, 255)代表白色,(0, 0, 0)代表黑色。從(0, 0, 0) ~ (255, 255, 255) 之間的任意組合都可以代表一個(gè)不同的顏色。
接下來我們可以通過下面代碼讀取圖片的 RGB
for i in range(width): for j in range(height): pos = (i, j) print(img.getpixel(pos)[:3])
圖片每個(gè)位置顏色由四元組表示,前三位分別是 RGB,第四位是 Alpha 通道,我們不需要關(guān)心。
有了 RGB ,我們就可以對其修改。
從圖中可以發(fā)現(xiàn),水印的 RGB 是 #d9d9d9,這里是用十六進(jìn)制表示的,其實(shí)就是(217, 217, 217)。
這三個(gè)顏色值都越靠近 255,顏色就越淡,當(dāng)它們都變成 255,也就成了白色。所以只要 RGB 都大于 217 的位置,我們都可以給它填成白色。即:RGB 三位數(shù)之和大于等于 651。
if sum(img.getpixel(pos)[:3]) >= 651: img.putpixel(pos, (255, 255, 255))
完整代碼如下:
from PIL import Image img = Image.open('watermark_pic.png') width, height = img.size for i in range(width): for j in range(height): pos = (i, j) if sum(img.getpixel(pos)[:3]) >= 651: img.putpixel(pos, (255, 255, 255)) img.save('watermark_removed_pic.png')
有了上面的基礎(chǔ),去除 PDF 的水印就簡單了,思路是將每頁 PDF 轉(zhuǎn)成圖片,然后修改水印的 RGB,最后輸出圖片即可。
安裝 pymupdf 庫,用來來操作 PDF
pip install pymupdf
讀取 PDF,并轉(zhuǎn)圖片
import fitz doc = fitz.open("數(shù)據(jù)結(jié)構(gòu)和算法手冊@公眾號渡碼.pdf") for page in doc: pix = page.get_pixmap()
該 PDF 共 480 頁,所以需要遍歷每一頁,并獲取每一頁對應(yīng)的圖片pix。pix對象類似于我們上面看到的img對象,可以讀取、修改它的 RGB。
page.get_pixmap() 這個(gè)操作是不可逆的,即能夠?qū)崿F(xiàn)從 PDF 到圖片的轉(zhuǎn)換,但修改圖片 RGB 后無法應(yīng)用到 PDF 上,只能輸出為圖片。
修改水印 RGB 跟剛才一樣,區(qū)別是這里的 RGB 是一個(gè)三元組,沒有 Alpha 通道,代碼如下:
from itertools import product for pos in product(range(pix.width), range(pix.height)): if sum(pix.pixel(pos[0], pos[1])) >= 651: pix.set_pixel(pos[0], pos[1], (255, 255, 255))
完整代碼如下:
from itertools import product import fitz doc = fitz.open("數(shù)據(jù)結(jié)構(gòu)和算法手冊@公眾號渡碼.pdf") page_no = 0 for page in doc: pix = page.get_pixmap() for pos in product(range(pix.width), range(pix.height)): if sum(pix.pixel(pos[0], pos[1])) >= 651: pix.set_pixel(pos[0], pos[1], (255, 255, 255)) pix.pil_save(f"pdf_pics/page_{page_no}.png", dpi=(30000, 30000)) print(f'第 {page_no} 頁去除完成') page_no += 1
這種方案是有缺點(diǎn)的,第一,輸出并非 PDF 格式;第二,輸出的圖片比較模糊,后續(xù)還有待優(yōu)化,最好是能直接修改 PDF。
到此這篇關(guān)于Python去除PDF水印的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Python去除PDF水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
jupyter notebook 的工作空間設(shè)置操作
這篇文章主要介紹了jupyter notebook 的工作空間設(shè)置操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04全網(wǎng)最詳細(xì)的PyCharm+Anaconda的安裝過程圖解
這篇文章主要介紹了全網(wǎng)最詳細(xì)的PyCharm+Anaconda的安裝過程圖解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01python smtplib模塊自動收發(fā)郵件功能(二)
這篇文章主要為大家詳細(xì)介紹了python smtplib模塊自動收發(fā)郵件功能的第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05python實(shí)現(xiàn)拓?fù)渑判虻姆椒ú襟E
拓?fù)渑判蚴菍τ邢驘o環(huán)圖進(jìn)行排序的一種算法,本文主要介紹了python實(shí)現(xiàn)拓?fù)渑判虻姆椒ú襟E,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03Python 實(shí)現(xiàn)鏈表實(shí)例代碼
這篇文章主要介紹了Python 實(shí)現(xiàn)鏈表實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04Python利用tkinter實(shí)現(xiàn)一個(gè)簡易番茄鐘的示例代碼
番茄鐘是番茄工作法使用的一個(gè)時(shí)間表,即選擇一個(gè)待完成的任務(wù),將番茄時(shí)間設(shè)為25分鐘,專注工作,中途不允許做任何與該任務(wù)無關(guān)的事,直到番茄時(shí)鐘響起,然后在紙上畫一個(gè)X短暫休息一下。本文用tkinter實(shí)現(xiàn)一個(gè)簡易番茄鐘,需要的可以參考一下2022-12-12Anaconda出現(xiàn)CondaHTTPError: HTTP 000 CONNECTION FAILED for url
使用anaconda創(chuàng)建一個(gè)新的環(huán)境,執(zhí)行“conda create -n scrapyEnv python=3.6”,結(jié)果出現(xiàn)了CondaHTTPError,下面我們就一起來了解一下解決方法吧2021-05-05Python實(shí)現(xiàn)打印螺旋矩陣功能的方法
這篇文章主要介紹了Python實(shí)現(xiàn)打印螺旋矩陣功能的方法,簡單描述了螺旋矩陣的概念、原理及Python實(shí)現(xiàn)方法,需要的朋友可以參考下2017-11-11Python中__new__()方法適應(yīng)及注意事項(xiàng)詳解
這篇文章主要介紹了Python中__new__()方法適應(yīng)及注意事項(xiàng)的相關(guān)資料,new()方法是Python中的一個(gè)特殊構(gòu)造方法,用于在創(chuàng)建對象之前調(diào)用,并負(fù)責(zé)返回類的新實(shí)例,它與init()方法不同,需要的朋友可以參考下2025-03-03