使用Python開發(fā)一個(gè)圖片OCR管理和文章下載工具
在日常工作中,我們經(jīng)常面臨兩個(gè)零碎但繁瑣的需求:一是管理大量的OCR(文字識(shí)別)圖片素材,需要頻繁查看、縮放圖片并保存識(shí)別結(jié)果;二是看到優(yōu)質(zhì)的公眾號(hào)文章,想把里面的圖片批量下載下來保存素材。
今天,我將通過一個(gè)完整的 Python GUI 項(xiàng)目,分享如何使用 wxPython 將這兩個(gè)功能整合到一個(gè)工具中。我們將重點(diǎn)分析如何自定義支持縮放/拖拽的圖片控件、實(shí)現(xiàn)“智能保存”邏輯以及編寫多線程爬蟲。
技術(shù)棧概覽
GUI 框架: wxPython (主要用于界面構(gòu)建)
圖像處理: Pillow (PIL) (用于圖片加載和預(yù)處理)
網(wǎng)絡(luò)爬蟲: requests + BeautifulSoup4 (用于抓取微信文章)
系統(tǒng)交互: subprocess (調(diào)用外部OCR程序), threading (防界面卡死)
架構(gòu)設(shè)計(jì)
程序的主體結(jié)構(gòu)采用 wx.Notebook(選項(xiàng)卡)布局,將應(yīng)用分為兩個(gè)獨(dú)立的 Panel:
OCRPanel: 負(fù)責(zé)圖片導(dǎo)入、預(yù)覽、調(diào)用外部OCR工具以及工程文件的保存(JSON格式)。
DownloaderPanel: 負(fù)責(zé)解析微信文章URL,批量下載圖片。
核心亮點(diǎn)一:自定義可縮放、拖拽的圖片畫布 (ImageCanvas)
在早期的 wxPython 開發(fā)中,我們常用 wx.StaticBitmap 顯示圖片,但它不支持縮放和移動(dòng),查看大圖細(xì)節(jié)非常不便。為了解決這個(gè)問題,我重寫了一個(gè) ImageCanvas 類。
1. 原理分析
這個(gè)控件繼承自 wx.Panel,核心在于綁定 EVT_PAINT 事件,使用 wx.GraphicsContext 進(jìn)行高性能繪圖。
平移(Pan): 監(jiān)聽 EVT_MOTION 和鼠標(biāo)點(diǎn)擊事件,計(jì)算鼠標(biāo)移動(dòng)的 dx 和 dy,更新圖片的繪制偏移量 offset_x 和 offset_y。
縮放(Zoom): 監(jiān)聽 EVT_MOUSEWHEEL。當(dāng)滾輪滾動(dòng)時(shí),更新 self.scale 變量。
2. 代碼解析
def on_paint(self, event):
dc = wx.BufferedPaintDC(self) # 使用雙緩沖防止閃爍
dc.Clear()
if self.image:
gc = wx.GraphicsContext.Create(dc)
if gc:
gc.PushState()
# 核心變換邏輯:先平移,再縮放
gc.Translate(self.offset_x, self.offset_y)
gc.Scale(self.scale, self.scale)
bmp = wx.Bitmap(self.image)
gc.DrawBitmap(bmp, 0, 0, self.image.GetWidth(), self.image.GetHeight())
gc.PopState()這段代碼的精髓在于 wx.GraphicsContext,它讓我們不需要手動(dòng)計(jì)算每個(gè)像素的位置,而是通過矩陣變換(Translate/Scale)輕松實(shí)現(xiàn)視圖操作。
核心亮點(diǎn)二:工程文件的“智能保存”邏輯
在許多工具軟件中,每次點(diǎn)擊保存都彈出“另存為”對話框是非常糟糕的體驗(yàn)。我們在 OCRPanel 中實(shí)現(xiàn)了類似 Word 的保存邏輯。
1. 狀態(tài)管理
我們在類中增加了一個(gè)變量 self.current_project_file 來記錄當(dāng)前工程是否已經(jīng)關(guān)聯(lián)了磁盤上的文件。
2. 邏輯流
新建/清空時(shí):將 self.current_project_file 置為 None。
點(diǎn)擊保存時(shí):
Case A (已有文件): 如果 current_project_file 存在,直接寫入 JSON,不彈窗。
Case B (新文件): 彈出 wx.TextEntryDialog 詢問工程名,保存成功后更新 current_project_file。
def on_save_project(self, event):
# ... 省略數(shù)據(jù)收集代碼 ...
# 智能判斷:是“保存”還是“另存為”
if self.current_project_file and os.path.exists(self.current_project_file):
# === 直接保存 ===
with open(self.current_project_file, 'w', encoding='utf-8') as f:
json.dump(self.current_project, f, ...)
else:
# === 新建工程,詢問名稱 ===
dlg = wx.TextEntryDialog(self, "請輸入工程名稱:", "保存新工程")
if dlg.ShowModal() == wx.ID_OK:
# ... 保存并更新 self.current_project_file ...
核心亮點(diǎn)三:健壯的微信文章圖片獲取
微信公眾號(hào)文章的圖片下載有兩個(gè)難點(diǎn):懶加載(Lazy Load)和防盜鏈參數(shù)。
1. 對抗懶加載
微信文章的 HTML 中,真實(shí)的圖片 URL 通常不在 src 屬性中(src 往往是一個(gè)占位圖),而是藏在 data-src 中。我們的爬蟲采用了多重策略提取 URL:
BeautifulSoup 解析: 優(yōu)先查找 data-src、data-original 等屬性。
正則兜底: 如果 HTML 解析遺漏,使用正則表達(dá)式 re.findall 直接從源碼中暴力匹配 https://mmbiz.qpic.cn/... 格式的鏈接。
2. URL 清洗
微信圖片 URL 往往帶有大量的參數(shù)(如 tp=webp),直接下載可能導(dǎo)致格式混亂。代碼中實(shí)現(xiàn)了 clean_image_url 方法,提取基礎(chǔ) URL,并根據(jù) Content-Type 智能判斷文件后綴(.jpg, .png, .gif)。
3. 多線程防卡死
GUI 程序最忌諱在主線程進(jìn)行網(wǎng)絡(luò)請求。我們在 DownloaderPanel 中使用了 threading:
# 錯(cuò)誤做法:直接調(diào)用下載函數(shù),界面會(huì)卡死直到下載完成 # self.download_images(url, save_path) # 正確做法:開啟新線程 threading.Thread(target=self.run_download_task, args=(url, save_path)).start()
同時(shí),為了在子線程中安全地更新 UI(如進(jìn)度條),我們使用了 wx.CallAfter,確保 UI 操作回到主線程執(zhí)行。
運(yùn)行結(jié)果

到此這篇關(guān)于使用Python開發(fā)一個(gè)圖片OCR管理和文章下載工具的文章就介紹到這了,更多相關(guān)Python圖片OCR管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python使用PaddleOCR實(shí)現(xiàn)PDF/圖片文字識(shí)別與版面還原
- Python使用Tesseract?OCR實(shí)現(xiàn)識(shí)別圖片中的文字
- Python基于OCR實(shí)現(xiàn)圖片識(shí)別翻譯工具功能(附源碼)
- 使用Python的pytesseract庫開發(fā)簡易OCR圖片文字識(shí)別工具
- Python中圖片與PDF識(shí)別文本(OCR)的全面指南
- Python中圖片與pdf識(shí)別文本的方法總結(jié)(OCR)
- 使用Python實(shí)現(xiàn)pdf轉(zhuǎn)圖片再進(jìn)行OCR識(shí)別
- python利用ddddocr包ocr識(shí)別圖片碼的實(shí)現(xiàn)
相關(guān)文章
Pycharm中安裝Pygal并使用Pygal模擬擲骰子(推薦)
這篇文章主要介紹了Pycharm中安裝Pygal并使用Pygal模擬擲骰子,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Python數(shù)據(jù)可視化之在Excel中插入圖表
在數(shù)據(jù)分析與展示的領(lǐng)域中,Python 憑借其強(qiáng)大的庫支持,成為眾多開發(fā)者與數(shù)據(jù)工作者的得力助手,今天就帶大家深入探索如何利用 Python 在 Excel 中插入圖表,實(shí)現(xiàn)數(shù)據(jù)可視化的進(jìn)階操作吧2025-04-04
使用Python開發(fā)一個(gè)簡單的本地圖片服務(wù)器
本文介紹了如何結(jié)合wxPython構(gòu)建的圖形用戶界面GUI和Python內(nèi)建的 Web服務(wù)器功能,在本地網(wǎng)絡(luò)中搭建一個(gè)私人的,即開即用的網(wǎng)頁相冊,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2025-04-04
python代碼 if not x: 和 if x is not None: 和 if not x is None:使用
這篇文章主要介紹了python代碼 if not x: 和 if x is not None: 和 if not x is None:使用介紹,需要的朋友可以參考下2016-09-09
Python 快速把多個(gè)元素連接成一個(gè)字符串的操作方法
join() 方法一個(gè)用于將序列中的元素以指定的分隔符連接成一個(gè)字符串的方法,這個(gè)方法通常用于字符串操作,這篇文章主要介紹了Python 快速把多個(gè)元素連接成一個(gè)字符串的方法,需要的朋友可以參考下2024-06-06
python實(shí)現(xiàn)自動(dòng)打卡小程序
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)打卡小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
Python讀取Word文檔中的Excel嵌入文件的方法詳解
這篇文章主要為大家詳細(xì)介紹了Python讀取Word文檔中的Excel嵌入文件的方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-12-12
簡單實(shí)例帶你了解Python的編譯和執(zhí)行全過程
python 是一種解釋型的編程語言,所以不像編譯型語言那樣需要顯式的編譯過程。然而,在 Python 代碼執(zhí)行之前,它需要被解釋器轉(zhuǎn)換成字節(jié)碼,這個(gè)過程就是 Python 的編譯過程,還不知道的朋友快來看看吧2023-04-04

