您好,登錄后才能下訂單哦!
在python中提取pdf圖片的方法有哪些?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
基于 fitz 庫和正則搜索
fitz 是 pymupdf 的子模塊,需要先用命令行安裝 pymupdf:
pip install pymupdf
但注意導入時使用 import fitz
導入模塊!
下面的代碼就利用 fitz
庫提取圖片需要通過正則匹配圖片元素,將模板元素轉化為像素后再以圖片形式寫出
import fitz import re import os file_path = r'C:\xxx\xxx.pdf' # PDF 文件路徑 dir_path = r'C:\xxx' # 存放圖片的文件夾 def pdf2image1(path, pic_path): checkIM = r"/Subtype(?= */Image)" pdf = fitz.open(path) lenXREF = pdf._getXrefLength() count = 1 for i in range(1, lenXREF): text = pdf._getXrefString(i) isImage = re.search(checkIM, text) if not isImage: continue pix = fitz.Pixmap(pdf, i) new_name = f"img_{count}.png" pix.writePNG(os.path.join(pic_path, new_name)) count += 1 pix = None pdf2image1(file_path, dir_path)
運行提取示例文件后結果如下:
可以看到,有一些很小的色塊也被提取成圖片,那么怎么過濾掉它們呢?
有一個簡單的方法是通過大小過濾,pix 像素在 fitz 庫中存在一個重要的方法 pix.size 可以反映像素多少,簡單的色素塊該值較低,可以通過設置一個閾值過濾。以閾值 10000 為例過濾:
import fitz import re import os file_path = r'C:\xxx\xxx.pdf' # PDF 文件路徑 dir_path = r'C:\xxx' # 存放圖片的文件夾 def pdf2image1(path, pic_path): checkIM = r"/Subtype(?= */Image)" pdf = fitz.open(path) lenXREF = pdf._getXrefLength() count = 1 for i in range(1, lenXREF): text = pdf._getXrefString(i) isImage = re.search(checkIM, text) if not isImage: continue pix = fitz.Pixmap(pdf, i) if pix.size < 10000: # 在這里添加一處判斷一個循環 continue # 不符合閾值則跳過至下 new_name = f"img_{count}.png" pix.writePNG(os.path.join(pic_path, new_name)) count += 1 pix = None pdf2image1(file_path, dir_path)
可以看到,全部圖片都被正常提取!
一看名字就知道這個庫的用處了,官方文檔為https://www.cnpython.com/pypi/pdf2image
可以簡單通過 pip install pdf2image
安裝,但poppler才是真正起做用的轉換器,因此需要額外安裝和配置:
windows用戶必須安裝poppler for Windows
,然后將bin/文件夾添加到PATH
Mac用戶必須安裝poppler for Mac
具體發揮作用的代碼官方文檔也給出了詳細的說明:
那么我們就分別嘗試這兩種方法:
from pdf2image import convert_from_path,convert_from_bytes import tempfile from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError import os file_path = r'C:\xxx\xxx.pdf' # PDF 文件路徑 dir_path = r'C:\xxx' # 存放圖片的文件夾 def pdf2image2(file_path, dir_path): images = convert_from_path(file_path, dpi=200) for image in images: if not os.path.exists(dir_path): os.makedirs(dir_path) image.save(file_path + f'\img_{images.index(image)}.png', 'PNG') pdf2image2(file_path, dir_path)
可以成功提取圖片。再試試第二種方法:
from pdf2image import convert_from_path,convert_from_bytes import tempfile from pdf2image.exceptions import PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError import os file_path = r'C:\xxx\xxx.pdf' # PDF 文件路徑 dir_path = r'C:\xxx' # 存放圖片的文件夾 def pdf2image3(file_path, dir_path): images = convert_from_bytes(open(file_path, 'rb').read()) for image in images: if not os.path.exists(dir_path): os.makedirs(dir_path) image.save(file_path + f'\img_{images.index(image)}.png', 'PNG') pdf2image3(file_path, dir_path)
可以看到結果和之前一致,PDF中全部圖片都被提取出來!
再補充一下。核心方法covert_from_bytes
包含大量參數,可以自行修改。幾個常用參數總結如下:
參數 | 意義 |
---|---|
pdf_path | PDF 文檔路徑 |
dpi | 圖像質量(如果是學術期刊雜志常見 300dpi) |
output_folder | 將生成的圖像寫入文件夾(而不是直接寫入內存) |
first_page | 起始轉換頁數 |
last_page | 轉換至哪一頁 |
fmt | 圖像格式,可以指定為 png,默認為 ppm |
thread_count | 允許參與轉換的線程數 |
userpw | PDF 的密碼 |
output_file | 輸出文件名 |
poppler_path | 指定 poppler 的安裝路徑,一開始配置好就無需指定 |
值得一提的是thread_count
參數,可以啟動多線程會大大加快轉換速度,尤其是 PDF 頁面較多時。有興趣的讀者可以做嘗試。
看完上述內容,你們掌握在python中提取pdf圖片的方法有哪些的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。