原由
Pyinstaller可將程式碼包裝成 exe檔, 但圖片檔無法一併包進去. 所以如果程式碼中需要存取圖片時, 此時又忘了將圖片copy給客戶, 那麼客戶會因為讀不到圖片而發生錯誤.
copy .exe檔給客戶是必然的, 但連圖檔也要copy給客戶, 這就說不過去. 如果那個圖檔是開發者的logo, 那麼客戶就可以把圖改成他自己想要的. 下場就是這程式是客戶自已開發的了.
網路上很多的教法, 包括 pyi-makespec產生.spec檔, 再加入圖檔位置, 這都只是把圖片copy到應用程式目錄中而以, 客戶可以自已修改. 再說了, 這個方法在 3.7版已失效了
解決思維
1. 將圖檔資料讀入, 轉成字串後, 存入 string_pic.py檔案
2. 在應用程式引入 string_pic.py, 即可取得圖片字串
圖片轉字串檔
將下面程式碼存成pic2py.py. 藍色的部份即要轉換的圖片檔名
import base64 def pic2py(pics, py_name): datas = [] for pic in pics: image = open(pic, 'rb') key = pic.replace('.', '_') value = base64.b64encode(image.read()).decode() image.close() datas.append('{0} = "{1}"\n'.format(key, value)) f = open('{0}.py'.format(py_name), 'w+') for data in datas: f.write(data) f.close() if __name__ == '__main__': pics = ["lora.png"] pic2py(pics, 'string_pic')
此時產生的 string_pic.py檔有如下的格式
lora_png = "iVBORw0KGgoAAAANSUhEUgAAAMYAAAB7CAYAAAAv................" icon_jpg = "iVBORw0KGgoAAAANS......................................."
程式引用
在應用程式中, 只需將 lora_png的變數放入如下的代碼即可轉成圖片
from string_pic import * from io import BytesIO from PIL import Image import base64 pil=Image.open(BytesIO(base64.b64decode(lora_png))) w, h=pil.size img=wx.Image(w,h) img.SetData(pil.convert("RGB").tobytes()) img.SetAlpha(pil.convert("RGBA").tobytes()[3::4]) img.SaveFile("test.png") bitmap=wx.Bitmap(img) icon=wx.Icon() icon.CopyFromBitmap(bitmap) self.SetIcon(icon)