用Python做一個“以圖搜番“的應用程序,再也不用愁動漫圖片的出處了!

前言

喜歡看動漫的朋友們大概都能體會到一個難受的事情,就是在論壇或者羣聊裏面看到一張動漫截圖,很想知道它的出處,但百度搜了一圈卻也沒有一個可靠結果,就很鬱悶。今天就來帶大家用Python做一個簡單的“以圖搜番”小應用。應用本身的實現不是很難的事情,其實就是調用別人的API接口來實現,主要目的還是通過這個案例來學習以下內容:

  • 學習如何用PyQt5做用戶交互界面(UI)
  • 學習如何使用Nuitka打包程序爲exe文件

PyQt5界面設計

如果用 Python 語言開發 跨平臺 的圖形界面的程序,主要有3種選擇:

  • Tkinter:基於Tk的Python庫,這是Python官方採用的標準庫,優點是作爲Python標準庫、穩定、發佈程序較小,缺點是控件相對較少。

  • wxPython:基於wxWidgets的Python庫,優點是控件比較豐富,缺點是穩定性相對差點、文檔少、用戶少。

  • PyQt5(或者PySide2):基於Qt 的Python庫,優點是控件比較豐富、跨平臺體驗好、文檔完善、用戶多。缺點是庫比較大,發佈出來的程序比較大。

本教程使用的就是PyQt5,它是Digia的一套Qt5應用框架與python的結合,同時支持2.x和3.x。本教程使用的是3.x。Qt庫由Riverbank Computing開發,是最強大的GUI庫之一 ,官方網站:https://www.riverbankcomputing.com/software/pyqt/。
PyQt5是由一系列Python模塊組成。超過620個類,6000函數和方法。能在諸如Unix、Windows和Mac OS等主流操作系統上運行。PyQt5有兩種證書,GPL和商業證書。
安裝方法:pip install PyQt5

使用Qt Designer繪製界面

在設計一個圖形化界面的應用時,我們需要先繪製出其大致佈局,可以在草稿紙上勾勒一下,然後通過PyQt5中的Qt Designer應用來設計,它的文件名叫designer.exe,找不到位置可以在本地文件中搜索一下:


下圖爲本應用的一個界面初步設計,通過標註的四個區域相互配合,即可完成一個UI設計,該工程會保存爲一個.ui後綴名的UI文件,最好放在Python代碼文件一起。本次界面設計並不複雜,兩個按鈕,一個打開圖片,另一個點擊後開始查詢;一個QComboBox部件,用於選擇備選結果;一個圖片顯示區域,顯示打開的查詢圖片,一個結果顯示區域,顯示查詢結果具體內容。界面下面是視頻顯示區域,即該圖片出現在原動畫中的視頻片段。

具體的Qt Designer基本使用方法我就不在這裏展開了,如果你第一次用,可以參考這個入門視頻教程:https://www.bilibili.com/video/BV1cJ411R7bP ,講得還挺好,我就是跟着這個視頻入門學習的。它的文字版教程在這裏:http://www.python3.vip/tut/py/gui/qt_01/

我是使用的VSCode編輯器,推薦一個插件——PYQT Integration,可以隨時預覽UI界面和編輯UI界面,也很方便把UI文件轉換成Python代碼。

視頻部件插入小技巧

在UI界面中加一個視頻顯示部分我花了不少時間去研究,主要因爲Qt Designer中沒有視頻播放器的小部件,於是我就有點懵了,雖然可以直接編輯Python代碼來弄,但爲了統一流程,還是希望能在Qt Designer中佈置好。經過一番研究,總結以下方法:
第一步:拖拽一個Containers中的Widget到編輯界面;
第二步:選擇Widget部件,右鍵選擇“提升爲…(Promote to …)”;

第三步:設置“提升的類名稱”爲QVideoWidget,“頭文件”爲PyQt5.QtMultimediaWidgets
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-i5MSN0LQ-1593942714477)(http://img.wildwind0.com/202020051143-r.png)]
第四步:點擊添加,然後點擊提升。
反應到編譯的Python代碼中,其實就是增加了一句from PyQt5.QtMultimediaWidgets import QVideoWidget

在使用時,可以參考下面代碼使用(僅僅是一個示例),此處僅僅播放視頻,沒有暫停、顯示進度條等功能,如需增加,可以參考這篇教程:https://stackoverflow.com/questions/57842104/how-to-play-videos-in-pyqt

from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer

# 首先初始化一個mediaPlayer
self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)
self.mediaPlayer.setVideoOutput(self.ui.VideoDisplay)

# 在需要使用這個mediaPlayer的函數中,從本地打開視頻並播放
self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(file_name)))
self.mediaPlayer.play()

解碼器下載

另外,需要下載一個解碼器,不然播放mp4視頻的時候會如下圖一樣報錯。解碼器的話下載安裝 LAV 解碼器就好,下載地址:LAV 0.74.1: Installer (both x86/x64)

功能實現

trace.moe API介紹與視頻

它背後的實現依靠的是大數據+基於內容的圖像檢索(Content-based image retrieval ,CBIR),“基於內容”意味着搜索分析圖像的內容,而不是與圖像相關的元數據,如關鍵字、標籤或描述。術語“內容”在這個上下文中可能指的是顏色、形狀、紋理或任何其他可以從圖像本身衍生出來的信息。CBIR使用起來比較方便,因爲它不需要標註信息,而純粹依賴元數據的搜索依賴於標註的質量和完整性。wikipedia上有列出很多CBIR engines,trace.moe則使用了Lire。對於圖像的描述,trace.moe則僅僅使用了顏色佈局(Color Layout )。另一方面就是大數據,其背後的數據支撐爲30096小時的視頻內容(大約26億幀),來自於3194部動畫,大約18.1 TB大小。7.46億幀索引(重複數據刪除後),數據庫大小爲140 GB。具體實現細節可以參考:trace.moe slidetrace.moe github 項目

如果你不關心實現細節,可以直接看下面的API接口使用。

import requests

img_path = 'xxx.png'
traceMoe_api = "https://trace.moe/api/search"
files = {"image": ('anime.png', open(img_path, 'rb'))}

res = requests.post(traceMoe_api, files=files)

返回一個json結果,內容如下:

其中docs則包含了可能的結果,其內容如下:

得到這些內容後,就可以下載對應的視頻片段:

url = f"https://trace.moe/preview.php?anilist_id={item['anilist_id']}&file={item['filename']}&t={item['at']}&token={item['tokenthumb']}"
video = requests.get(url)
with open(item['filename'], 'wb') as f:
    f.write(video.content)

當然,也不是每天無限制請求的,普通用戶每天只能查詢150次

使用Nuitka打包成exe文件

Nuitka的作用是將Python程序轉換成C語言的可執行elf文件。這樣在運行時就可以享受到C語言處理過程中的優化,提高速度。經測試,Nuitka打包後的exe比Pyinstaller打包後的exe運行速度提升30%,PyQT5的UI文件轉換成py文件轉換成C語言後,界面秒開呀。
第一步下載MinGW64 8.1,解壓文件到C盤根目錄,並將bin路徑加入到環境變量中。然後安裝Nuitka:pip install nuitka

]
這樣就表示成功了:

import的系統庫,使用python3x.dll來執行,其他自己實現的UI界面和數據庫的連接以及函數和功能實現,需要加密(反編譯)和快速反應的,用戶的體驗就在這裏,這部分藉助Nuitka來實現。
以下是Nuitka的關鍵命令段:
–nofollow-imports #所有的import全部不使用,交給python3x.dll執行
–follow-import-to=need #need爲你需要編譯成C/C++的py文件夾命名

——引用自:Python打包exe(32/64位)-Nuitka再下一城

第二步:調試階段,逐個加入所需的輪子文件:
首先運行
nuitka --standalone --mingw64 --show-memory --show-progress --nofollow-imports --plugin-enable=qt-plugins --follow-import-to=need --output-dir=output app_main.py
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-oU533ih4-1593942714480)(http://img.wildwind0.com/202020051445-y.png)]
然後運行output\app_main.dist中的app_main.exe,逐個找到缺的輪子的文件,並加入到output\app_main.dist目錄下,如下圖,表明缺少requests等庫,則可以利用Everything,XSearch等軟件快速定位文件所在地(關注公衆號:野風同學,回覆“文件查找”即可獲取軟件)。加到可以運行爲止。記住把這些庫文件單獨另外找一個文件夾放着,後面需要複製到正式輸出的文件夾中



第三步:生成階段,
運行
nuitka --standalone --windows-disable-console --mingw64 --nofollow-imports --show-memory --show-progress --plugin-enable=qt-plugins --follow-import-to=need --recurse-all --output-dir=output app_main.py,然後將剛剛找到庫文件複製到app_main.dist文件夾下。這樣就基本完成了打包,進入app_main.dist中,點擊app_main.exe即可運行(前提是安裝了LAV 解碼器,不然視頻不會顯示!)。

下面演示一下:
https://zhuanlan.zhihu.com/p/156851623


本文Python源碼及exe打包後的軟件,關注我的公衆號“野風同學”,回覆“以圖搜番”即可獲取。
一個程序員的自我成長之路,持續分享機器學習基礎與應用、LeetCode面試算法和Python基礎與應用等技術乾貨文章,同時也經常推薦高質量軟件工具、網站和書籍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章