前言:
課堂小專,不到半學期的時間要做個修圖軟體。
老師評分比較高,所以得肝一點o( ̄┰ ̄*)ゞ
不過倒是學到很多js操作。
操作畫面
Python UI介面選擇
一開始課堂上是教預設的Qt軟體,但我覺得Qt醜醜的,所以忍不住去嘗試其他框架。
Tkinter
跟以前做window form很像,用程式碼掛載與編排UI物件。
Qt Designer
在Anaconda預設功能, Anaconda資料夾下找到designer.exe啟動。
排版檔案會取為.ui附檔名,操作邏輯與Tk類似。
範例: 讀取圖片、變暗處理。
Flask / Django
使用Python編寫的輕量級Web應用框架。
範例: flask基本頁面,但其網頁模板概念跟Django雷同。
範例: Django網頁
創個views.py檔案,裡面定義Hello頁面內容
在urls.py定義Hello頁面的網址
綜合比較下來,我選擇開發桌面應用程式的eel,若小專題在展示的時候因為網路問題lag那可就掉渣了。( ̄┰ ̄*)
框架名稱 |
優點 |
缺點 |
Tkinter |
像是用Python程式碼撰寫介面的Qt Designer。 |
邏輯與QtDesigner類似,同樣無法解決程式碼攏長、難做排版等問題。 |
Flask/Django |
較完整且可部屬網頁的web應用框架。 |
Python與前端邏輯溝通較複雜,需使用ajax等呼叫方式。 |
eel |
旨在於結合前端技術開發桌面應用程式,前後端邏輯串接容易。 |
我試著包在docker環境下部屬但失敗多次,雖然文獻不多但似乎eel不支援網站部屬。 |
EEL基本使用
我是觀看他的影片:
python 呼叫js方法
python 方法上加@eel.expose 讓js端可以呼叫。
func.js檔案:
Async方法使用
按下按鈕後,js端等待python處理結果後出現alert。
JS-EEL圖檔傳輸
跨語言開發首先遇到的問題便是如何傳遞圖片資訊? 由於處理後的圖片需轉換成前端html可顯示的based64編碼,其跟openCV imread讀取進來的圖片格式之間的關係又是如何? 為此我必須先了解從HTML的input 標籤輸入的圖片至python端之間的格式與轉換。我整理出如下圖這個流程:
(1.) 由input標籤開啟的圖片為大型二進位檔物件(Binary Large Object ,blob),代表了一個相當於檔案(原始資料)的不可變物件。
(2.) 需實作js的FileReader物件,將blob轉碼成based64字串。
(3.) 透過eel框架傳送字串至Python端。
(4.) 使用based64處理套件將字串解析成byte陣列。
(5.) 透過numpy將byte陣列轉成uint8陣列。
(6.) 透過cv2套件將uint陣列解碼成圖片,此時得到的檔案形同於imread進來的圖片。
(7.) 使用圖片資料進行影像處理操作。
(8.) 將處理完的圖片回傳至前端作顯示時,逆著遵循前述的轉碼步驟,先將圖片轉成byte陣列,再以based64編碼成字串透過eel框架溝通回前端,由js接收並設定img標籤的src。
JS讀取圖片
使用jQuery偵測input標籤Change事件,搭配fileReader轉成base64字串。
Python接收圖片
將base64字串透過轉碼,轉程opencv可使用的格式。
搭配OpenCV
範例: 將圖片轉灰階
Python傳回圖片
直方圖
直方圖常常用在檢視圖片顏色趨勢、集中位置等等。
一開始使用Chart.js插件:
js端
Python端
注意np array無法直接傳輸,所以要轉成一般array。
瀏覽器無法像Python的numpy與的plot套件快速做統計與圖表,加上本身也不支援多線程(Multi-threading),因此當圖片解析度大,需要統計的數變多,前端直方圖生成便會延遲,除了採用異步執行避免程序卡死外,我還試過多個輕量圖表套件如Chart.js、dygraphs、EChart.js,尋找對資料最友善的解決方案,雖然目前前端直方圖生成仍有延遲存在,是日後需想辦法解決的問題(目前已是在Python生成直方圖數據,再傳輸至前端表現,理論上只需處理255*3個顏色資料,我認為會卡的點在於繪製與自動尋找最小至最大值區間)。
等化功能
等化是將像素顏色拉得平均一點。
操作Hot Key
註冊document事件,並藉由array紀錄各步驟的base64字串。
JS寫出圖片
拖拉圖片
JS事件
在修改圖片時觸發事件,如此便能最後續處理,例如圖片縮圖僅需在圖片有更動時才須更新。
顏色通道
圖片RGB拆成可以分別開關的通道,在P圖的時候常會從通道中選一張二值化效果最好的通道做遮罩,不過目前本軟體的通道只能顯示、不能編輯(;´༎ຶД༎ຶ`) (時間不夠..)。
在地化
加上為了降低開發環境複雜度,本軟體前端使用較原生的JQuery輔助,沒有用如React.js等完整的web生態系統,能使用的工具較為受限,最後使用行之有名的i18n在地化解決方案應付小需求翻譯。
後紀:
與全班做法不同,在學習的路上總是有些孤獨、無助。所幸社群的力量,每當我遇到困難時總是能在StackOverflow等平台找到方法。也感謝eel團隊釋出這個便捷的框架,我也想盡力將所學知識、概念紀錄並分享下來回饋社群。
這個專案少說也陪伴我快半個學期,每天埋頭在打程式、修BUG,最後也算是來到個Ending,就像小孩子畢業一般,想盡力寫好文件、交代擴充方法等等送它最後一程,儘管我總是會有點自卑的覺得「某某功能太基本不值得介紹」所以少寫在文件裡,也希望各位能多看看這學期的努力結晶。
附錄:
主要功能與對應選單做成表格整理如下:
功能名稱 |
套用結果 |
選單 |
調整大小 |
|
|
旋轉 |
|
*旋轉操作可即時預覽,按下套用後自動補齊邊界。 |
等化 |
|
*等化後自動更新直方圖結果 |
顏色調整 |
|
*貼心提供色彩對照表方便調整 |
色彩分割 |
|
*範例:抓取藍色頭髮。 |
曝光校正 |
|
|
對比校正 |
|
|
高斯模糊 |
|
|
去除雜訊 |
|
|
美肌 |
|
|
銳化 |
|
|
邊緣抽取 |
|
*有做彩色/灰階圖兩種處理,若只要白線需先使用「灰階」功能。 |
邊緣保留 |
|
|
鉛筆風格 |
|
特色 |
|
毛邊模糊 |
|
魚眼 |
|
波紋模糊 |
|
|
放射像素模糊 |
|
|
漣漪效果 |
|
|
扭轉效果 |
|
|
運動模糊 |
|
|
放射模糊 |
|
|
標示人臉 |
|
|