文章目錄
- 0 引言
- 1 解決思路及流程
- 1.1 思路
- 1.2 代碼實現
- 2 完整代碼與效果
- 3 總結
0 引言
沒錯,這是連續劇。女友對上一篇【fitz+OpenCV】去除PDF圖片中的水印得到的去水印效果很滿意,于是問我可不可以再幫她處理一下另一個PDF文件,我二話不說答應了下來。原PDF文件是一本教材的電子版,每頁都是一張圖片,和上一篇文章中PDF的類型相同,不過本文中需要解決的問題是,原圖中文字顏色太淺,看著費眼睛,如下圖所示,需要將文字顏色加深。
1 解決思路及流程
1.1 思路
在大致分析了PDF組成后(其中紅色的為筆記標注,和頁面圖片單獨存在),這個問題的解決思路也相當明晰了,便是將每頁的圖片單獨提取出來,對圖片進行文字加深處理,這里可以通過增加圖片對比度實現(對比度就是畫面中明暗部分的亮度比,對比度越高,則圖像中明暗部分的差異就越大。根據這一原理,將對比度增大后,原本顏色較深的文字部分將會更深,反之,顏色較淺的背景將會更亮)。
1.2 代碼實現
在代碼方面中,我們依然采用fitz
(pip install PyMuPDF
)作為PDF處理庫,圖片的處理則是基于圖像庫PIL
(pip install pillow
)。
首先我們打開待處理的PDF文件,對每頁進行遍歷,提取每頁的圖片,為了防止個別頁面存在多張圖片,又嵌套了個for循環以遍歷頁內圖片。
doc = fitz.open(input_pdf) # 打開原PDF
for page_num in range(len(doc)):# 獲取頁面圖片page = doc.load_page(page_num)page_imgs = page.get_images()for page_img in page_imgs:xref = page_img[0]img_info = doc.extract_image(xref)img = Image.open(io.BytesIO(img_info["image"])) # 轉換為 PIL Image,方便處理
接下來處理每張圖片,factor
為對比度值,取1函數返回原圖像,如果要增加圖像對比度,該參數應大于1.0,本文示例中取3.0。
# 增強圖片
enhancer = ImageEnhance.Contrast(img) # 增強對比度(使文字更清晰)
enhanced_img = enhancer.enhance(factor=contrast)
用增強后的圖片替換原圖片,這一步僅僅改變了背景圖片的信息,不影響前景的筆記標注。其中quality
參數用于控制圖像的質量,決定圖像的體量與清晰度,progressive
用于控制是否生成漸進式JPEG,實測該保存方式得到的圖片體積更小,dpi
參數用于控制圖片兩個方向的dpi。
# 替換原圖片
bio = io.BytesIO()
enhanced_img.save(bio, format=img_info["ext"], quality=50, progressive=True, dpi=(300, 300))
page.replace_image(xref, stream=bio)
最后一步,在所有頁面處理完成后,保存輸出處理后的PDF。
# 保存PDF
doc.save(output_pdf)
doc.close()
2 完整代碼與效果
完整代碼如下:
import io
import fitz # PyMuPDF
from PIL import Image, ImageEnhancedef process_pdf(input_pdf, output_pdf, contrast):doc = fitz.open(input_pdf) # 打開原PDFfor page_num in range(len(doc)):# 獲取頁面圖片page = doc.load_page(page_num)page_imgs = page.get_images()for page_img in page_imgs:xref = page_img[0]img_info = doc.extract_image(xref)img = Image.open(io.BytesIO(img_info["image"])) # 轉換為 PIL Image,方便處理# 增強圖片enhancer = ImageEnhance.Contrast(img) # 增強對比度(使文字更清晰)enhanced_img = enhancer.enhance(factor=contrast)# 替換原圖片bio = io.BytesIO()enhanced_img.save(bio, format=img_info["ext"], quality=50, progressive=True, dpi=(300, 300))page.replace_image(xref, stream=bio)# 保存PDFdoc.save(output_pdf)doc.close()print(f"PDF處理完成!輸出文件: {output_pdf}")if __name__ == "__main__":input_pdf = 'example.pdf'output_pdf = 'output.pdf'process_pdf(input_pdf, output_pdf, contrast=3.0)
處理效果如下圖所示:
效果還是不錯的。
3 總結
該方法和上一篇文章中的方法存在一個共性問題,便是生成的PDF文件體量太大,比原本文件的大了近3~4倍,該問題打算后面有時間研究一下。