天天看點

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

文章目錄

    • 前言
    • PyQt5界面設計
      • 使用Qt Designer繪制界面
      • 視訊部件插入小技巧
      • 解碼器下載下傳
    • 功能實作
      • trace.moe API介紹與視訊
    • 使用Nuitka打包成exe檔案

前言

喜歡看動漫的朋友們大概都能體會到一個難受的事情,就是在論壇或者群聊裡面看到一張動漫截圖,很想知道它的出處,但百度搜了一圈卻也沒有一個可靠結果,就很郁悶。今天就來帶大家用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

,找不到位置可以在本地檔案中搜尋一下:

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

下圖為本應用的一個界面初步設計,通過标注的四個區域互相配合,即可完成一個UI設計,該工程會儲存為一個

.ui

字尾名的UI檔案,最好放在Python代碼檔案一起。本次界面設計并不複雜,兩個按鈕,一個打開圖檔,另一個點選後開始查詢;一個QComboBox部件,用于選擇備選結果;一個圖檔顯示區域,顯示打開的查詢圖檔,一個結果顯示區域,顯示查詢結果具體内容。界面下面是視訊顯示區域,即該圖檔出現在原動畫中的視訊片段。

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

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

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

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

視訊部件插入小技巧

在UI界面中加一個視訊顯示部分我花了不少時間去研究,主要因為Qt Designer中沒有視訊播放器的小部件,于是我就有點懵了,雖然可以直接編輯Python代碼來弄,但為了統一流程,還是希望能在Qt Designer中布置好。經過一番研究,總結以下方法:

第一步:拖拽一個Containers中的Widget到編輯界面;

第二步:選擇Widget部件,右鍵選擇“提升為…(Promote to …)”;

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

第三步:設定“提升的類名稱”為

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)

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

功能實作

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 slide和trace.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結果,内容如下:

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

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

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

得到這些内容後,就可以下載下傳對應的視訊片段:

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次

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

使用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

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

]

這樣就表示成功了:

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

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等軟體快速定位檔案所在地(關注公衆号:野風同學,回複“檔案查找”即可擷取軟體)。加到可以運作為止。記住把這些庫檔案單獨另外找一個檔案夾放着,後面需要複制到正式輸出的檔案夾中。

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

第三步:生成階段,

運作

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基礎與應用等技術幹貨文章,同時也經常推薦高品質軟體工具、網站和書籍。

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