Python實現(xiàn)從常規(guī)文檔中提取圖片的方法詳解
1. 環(huán)境準備
安裝必需庫
pip install python-docx PyMuPDF openpyxl beautifulsoup4 pillow pip install pdfplumber # PDF解析備用方案 pip install tk # Python自帶,無需安裝
工具選擇
開發(fā)環(huán)境:VSCode + Python插件
調(diào)試工具:Python IDLE(初學者友好)
打包工具:pyinstaller(可選,用于生成exe)
2. 項目架構(gòu)設(shè)計
image-extractor/
├── main.py # 主程序入口
├── core/
│ ├── docx_extractor.py
│ ├── pdf_extractor.py
│ ├── excel_extractor.py
│ └── html_extractor.py
└── outputs/ # 默認輸出目錄
3. 核心功能實現(xiàn)
(1) Word文檔提取 (docx_extractor.py)
import zipfile import os from PIL import Image def extract_docx_images(file_path, output_dir): # 解壓docx文件 with zipfile.ZipFile(file_path, 'r') as zip_ref: # 提取media文件夾內(nèi)的圖片 image_files = [f for f in zip_ref.namelist() if f.startswith('word/media/')] for img_file in image_files: # 保存圖片到輸出目錄 zip_ref.extract(img_file, output_dir) # 重命名文件 src = os.path.join(output_dir, img_file) dst = os.path.join(output_dir, os.path.basename(img_file)) os.rename(src, dst) return len(image_files)
(2) PDF文件提取 (pdf_extractor.py)
import fitz # PyMuPDF import os def extract_pdf_images(file_path, output_dir): doc = fitz.open(file_path) img_count = 0 for page_num in range(len(doc)): page = doc.load_page(page_num) images = page.get_images(full=True) for img_index, img in enumerate(images): xref = img[0] base_image = doc.extract_image(xref) img_data = base_image["image"] # 保存為PNG img_path = os.path.join(output_dir, f"pdf_page{page_num}_img{img_index}.png") with open(img_path, "wb") as f: f.write(img_data) img_count += 1 return img_count
(3) Excel文件提取 (excel_extractor.py)
from openpyxl import load_workbook import os def extract_excel_images(file_path, output_dir): wb = load_workbook(file_path) img_count = 0 for sheet in wb.worksheets: for image in sheet._images: # 獲取圖片數(shù)據(jù) img = image._data img_path = os.path.join(output_dir, f"excel_{sheet.title}_img{img_count}.png") with open(img_path, "wb") as f: f.write(img) img_count += 1 return img_count
(4) HTML文件提取 (html_extractor.py)
import requests from bs4 import BeautifulSoup import os import base64 def extract_html_images(html_path, output_dir): if html_path.startswith('http'): response = requests.get(html_path) soup = BeautifulSoup(response.text, 'html.parser') else: with open(html_path, 'r') as f: soup = BeautifulSoup(f.read(), 'html.parser') img_tags = soup.find_all('img') img_count = 0 for img in img_tags: src = img.get('src') if src.startswith('data:image'): # 處理base64編碼圖片 header, data = src.split(',', 1) img_format = header.split('/')[1].split(';')[0] img_data = base64.b64decode(data) img_path = os.path.join(output_dir, f"html_img{img_count}.{img_format}") with open(img_path, 'wb') as f: f.write(img_data) img_count += 1 return img_count
4. 交互界面開發(fā) (main.py)
import tkinter as tk from tkinter import filedialog, messagebox from core import docx_extractor, pdf_extractor, excel_extractor, html_extractor import os class ImageExtractorApp: def __init__(self, root): self.root = root self.root.title("多格式圖片提取工具") # 文件路徑變量 self.file_path = tk.StringVar() self.output_dir = tk.StringVar(value="outputs") # 創(chuàng)建界面組件 self.create_widgets() def create_widgets(self): # 文件選擇 tk.Label(self.root, text="選擇文件:").grid(row=0, column=0, padx=5, pady=5) tk.Entry(self.root, textvariable=self.file_path, width=40).grid(row=0, column=1) tk.Button(self.root, text="瀏覽", command=self.select_file).grid(row=0, column=2) # 輸出目錄 tk.Label(self.root, text="輸出目錄:").grid(row=1, column=0) tk.Entry(self.root, textvariable=self.output_dir, width=40).grid(row=1, column=1) tk.Button(self.root, text="選擇目錄", command=self.select_output_dir).grid(row=1, column=2) # 執(zhí)行按鈕 tk.Button(self.root, text="開始提取", command=self.start_extraction).grid(row=2, column=1, pady=10) # 日志區(qū)域 self.log_text = tk.Text(self.root, height=10, width=50) self.log_text.grid(row=3, column=0, columnspan=3) def select_file(self): file_types = [ ('支持的文件類型', '*.docx *.pdf *.xlsx *.html'), ('Word文檔', '*.docx'), ('PDF文件', '*.pdf'), ('Excel文件', '*.xlsx'), ('網(wǎng)頁文件', '*.html') ] self.file_path.set(filedialog.askopenfilename(filetypes=file_types)) def select_output_dir(self): self.output_dir.set(filedialog.askdirectory()) def start_extraction(self): file_path = self.file_path.get() output_dir = self.output_dir.get() if not os.path.exists(output_dir): os.makedirs(output_dir) ext = os.path.splitext(file_path)[1].lower() try: if ext == '.docx': count = docx_extractor.extract_docx_images(file_path, output_dir) elif ext == '.pdf': count = pdf_extractor.extract_pdf_images(file_path, output_dir) elif ext == '.xlsx': count = excel_extractor.extract_excel_images(file_path, output_dir) elif ext == '.html': count = html_extractor.extract_html_images(file_path, output_dir) else: messagebox.showerror("錯誤", "不支持的文件類型") return self.log_text.insert(tk.END, f"成功提取 {count} 張圖片到 {output_dir}\n") except Exception as e: messagebox.showerror("錯誤", f"提取失敗: {str(e)}") if __name__ == "__main__": root = tk.Tk() app = ImageExtractorApp(root) root.mainloop()
5. 使用說明
操作步驟
1.運行 main.py
2.點擊 瀏覽 選擇文件 (支持.docx/.pdf/.xlsx/.html)
3.選擇輸出目錄(默認 outputs)
4.點擊 開始提取
5.查看底部日志區(qū)域的提取結(jié)果
效果示例
成功提取 5 張圖片到 outputs/
成功提取 3 張圖片到 outputs/
6. 常見問題解決
Q1: Excel圖片無法提取?
原因:openpyxl只能提取嵌入式圖片,無法提取浮動圖片
解決方案:改用xlrd+圖像坐標識別(需更復(fù)雜處理)
Q2: PDF提取的圖片模糊?
原因:PDF內(nèi)嵌低分辨率圖片
解決方案:使用pdfplumber的更高精度提取模式
Q3: 程序無響應(yīng)?
原因:大文件處理耗時阻塞主線程
解決方案:改用多線程處理(參考threading模塊)
7. 項目擴展建議
增加批量處理:支持文件夾批量導(dǎo)入
添加圖片預(yù)覽:在界面中顯示縮略圖
支持壓縮包:直接解壓ZIP/RAR文件并處理內(nèi)容
增加格式轉(zhuǎn)換:自動轉(zhuǎn)換HEIC/WEBP等特殊格式
以上就是Python實現(xiàn)從常規(guī)文檔中提取圖片的方法詳解的詳細內(nèi)容,更多關(guān)于Python提取圖片的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用pandas中的DataFrame數(shù)據(jù)繪制柱狀圖的方法
下面小編就為大家分享一篇使用pandas中的DataFrame數(shù)據(jù)繪制柱狀圖的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04python如何實現(xiàn)全角半角的相互轉(zhuǎn)換
這篇文章主要介紹了python如何實現(xiàn)全角半角的相互轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11Python實現(xiàn)雙向RNN與堆疊的雙向RNN的示例代碼
這篇文章主要為大家詳細介紹了如何利用Python語言實現(xiàn)雙向RNN與堆疊的雙向RNN,文中詳細講解了雙向RNN與堆疊的雙向RNN的原理及實現(xiàn),需要的可以參考一下2022-07-07python中的?sorted()函數(shù)和sort()方法區(qū)別
這篇文章主要介紹了python中的?sorted()函數(shù)和sort()方法,首先看sort()方法,sort方法只能對列表進行操作,而sorted可用于所有的可迭代對象。具體內(nèi)容需要的小伙伴可以參考下面章節(jié)2022-02-02tf.truncated_normal與tf.random_normal的詳細用法
本篇文章主要介紹了tf.truncated_normal與tf.random_normal的詳細用法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03Python并行編程多線程鎖機制Lock與RLock實現(xiàn)線程同步
這篇文章主要為大家介紹了Python并行編程多線程鎖機制Lock與RLock實現(xiàn)線程同步示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07