簡體   English   中英

Pyinstaller 和 --onefile:如何在 exe 文件中包含圖像

[英]Pyinstaller and --onefile: How to include an image in the exe file

我使用 Pyinstaller 創建了一個 exe 文件。

pyinstaller.exe --onefile --icon='Loco.ico program.py

在程序中,我在繪圖中包含一個圖像,當我在其文件夾中單獨運行程序時,我得到以下信息:

IOError: [Errno 2] No such file or directory: 'Logo.png'

一種解決方案是將圖像包含在 exe 的文件夾中,如下面的鏈接所示:

pyinstaller 不顯示圖像和圖標

但話又說回來, --onefile 的全部意義就是擁有它,而不需要另外的圖像。 我認為解決方案可能在此鏈接中,但我還沒有理解。

使用 PyInstaller (--onefile) 捆綁數據文件

我的規范文件如下所示:

# -*- mode: python -*-
a = Analysis(['AMOS_Visualizer.py'],
    pathex=['C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting'],
    hiddenimports=[],
    hookspath=None,
    runtime_hooks=None)

pyz = PYZ(a.pure)
exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name='AMOS_Visualizer.exe',
      debug=False,
      strip=None,
      upx=True,
      console=True , icon='AMOS.ico')

編輯:

我相信我找到了解決問題的方法。

# -*- mode: python -*-
a = Analysis(['AMOS_Visualizer.py'],
         pathex=['C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting'],
         hiddenimports=[],
         hookspath=None,
         runtime_hooks=None)

for d in a.datas:
    if 'pyconfig' in d[0]:
        a.datas.remove(d)
        break

a.datas += [('Logo.png','C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting\\Logo.png', 'Data')]
pyz = PYZ(a.pure)
exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      name='AMOS_Visualizer.exe',
      debug=False,
      strip=None,
      upx=True,
      console=True, icon='C:\\Users\\elu\\PycharmProjects\\Prosjektet\\Forsok splitting\\AMOS.ico')

並將以下內容添加到我的 main.py 腳本中

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    try:
        # PyInstaller creates a temp folder and stores path in _MEIPASS
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

Logo = resource_path("Logo.png")

如果您使用的是 Qt Designer,您可以通過創建資源文件並將所需的所有圖像(包括 Logo.png)添加到該資源來實現。

要創建資源文件,您可以按照使用 QT Designer 在 GUI 中插入圖像中的步驟進行操作。

在資源文件中插入圖片后,將 Logo.png 分配給 Window 圖標,保存 QtDesigner 界面並使用命令轉換資源文件: pyrcc4 -py3 resourcetest.qrc -o resourcetest_rc.py

最后,使用 --onefile 選項創建 exe 文件。 無需編輯規范文件。

這是以下內容的變體: 使用 PyInstaller (--onefile) 捆綁數據文件,並且給定的答案更清晰。

在 2 行中:

  1. 您必須將圖像文件添加到“數據”中(在您的規范文件中或使用 PyInstaller 掛鈎腳本)
  2. 如果存在,請使用 sys._MEIPASS,
    使用單行base_path = getattr(sys, '_MEIPASS', '.')+'/'獲取“root_path”變量以連接到所有文件的路徑。
    然后, filepath = base_path + filepath

在“hiddenimports = []”之前添加“datas = ['您的文件的位置']”。 會的。 就我而言,這有效

    # -*- mode: python -*-

block_cipher = None


a = Analysis(['embed.py'],
             pathex=['C:\\Users\\Aravind\\Desktop\\exe'],
             binaries=[],
             datas=['C:\\Users\\Aravind\\Desktop\\exe\\dist\\map.png'],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='embed',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

我已經嘗試了很多,但一個小時后就奏效了:

當我第一次運行我的程序文件 MilaBild.py 時:

pyinstaller -F -w MilaBild.py

它接縫創建我需要添加以下內容的“.spec”文件,如上面其他評論中所述:

a.datas += [('rosa.png','C:\\Python34\\rosa.png', 'DATA')]

我的圖像文件的名稱是 rosa.png。 它與我的程序文件 MilaBild.py 位於同一目錄中。

然后我還必須在我的實際程序文件中添加上面注釋中提到的部分:

def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
    # PyInstaller creates a temp folder and stores path in _MEIPASS
    base_path = sys._MEIPASS
except Exception:
    base_path = os.path.abspath(".")

return os.path.join(base_path, relative_path)

然后我添加了將文件獲取到變量的部分並且它起作用了:

rosa = resource_path("rosa.png")

我嘗試了很多,但完成這項工作花了我一個小時。 稍后我將嘗試使用兩個圖像、聲音和子目錄來制作它。 但現在是 23 點 45 分,那將是另一天,到目前為止,我對此感到非常高興,這對我來說是一個很好的休息時間。

最后,它比我在各種網頁和這里找到的要簡單。

1)當代碼作為編譯的可執行文件運行時,您在代碼中指定臨時目錄中的相對路徑:

if getattr(sys, 'frozen', False): # Running as compiled
    running_dir = sys._MEIPASS + "/files/" # Same path name than pyinstaller option
else:
    running_dir = "./" # Path name when run with Python interpreter
iconFileName = running_dir + "mylogo.ico"
if os.path.isfile(iconFileName):
    root.iconbitmap(iconFileName) # Exemple for tkinter usage

2)您在創建的臨時目錄中提供路徑,您的文件將存儲在編譯器選項中:

pyinstaller --onefile --add-binary "mylogo.ico;files" -i mylogo.ico myMainPrg.py

這樣,您不必知道文件在開發中的完整路徑以及在生產中安裝它們的位置。

為此苦苦掙扎。 要知道的關鍵是,對於 --onefile 構建,您的圖像存儲在 sys._MEIPASS 文件夾中。

我的 tkinter 應用程序中的這行代碼破壞了我的 .exe:

self.wm_iconbitmap("favicon.ico")

為了修復它,我將其替換為:

self.wm_iconbitmap(get_path("favicon.ico"))

get_path() 是我添加到模塊中的一個小函數:

def get_path(filename):
    if hasattr(sys, "_MEIPASS"):
        return os.path.join(sys._MEIPASS, filename)
    else:
        return filename

對於上下文,我在 CLI 中運行此命令來構建 .exe:

pyinstaller --noconfirm --onefile --windowed --add-data "C:/Users/[...]/favicon.ico;."  "C:/Users/[...]/main.py"

注意,在 Win10 上運行。

感謝許多其他 Stack Overflow 貢獻者。

清晰明確的指南

盡管網上有解釋,但我還是花了幾個小時才想出一個獨立的應用程序,它包含多個圖像,執行時不打開控制台,並且只合並在一個文件中。 這是我至少適用於 Mac OS 的解決方案(稍后我將發布適用於 Windows 的解決方案):

第 1 步:更改目錄

更改為可執行文件所在的目錄:

cd PATH_OF_YOUR_FILE

確保您的程序所需的圖像也在您要使其可執行的 Python 文件所在的文件夾中。

第 2 步:將代碼添加到 Python 文件

將以下內容添加到要使其可執行的 Python 文件中:

import os

def resource_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")

    return os.path.join(base_path, relative_path)

resource_path("FILENAME")替換文件名。

例子:

image1 = Image.open("image.png")

# to:

image1 = Image.open(resource_path("image.png"))

第三步:創建可執行文件

現在運行以下代碼(替換圖像名稱和文件名):

pyinstaller --onefile --windowed --add-data "picture1.jpeg:." --add-data "picture2.png:." your_file.py

注意:可以添加任意數量的圖像。

說明:

--onefile :創建一個捆綁的單文件可執行文件。 同義詞: -F

--windowed :確保在執行期間不打開任何控制台。 同義詞: -w--noconsole

你完成了! 🎉

該應用程序現在位於dist目錄中,該目錄與您的 Python 文件位於同一目錄中。

現在應該可以將它拖到另一台 Mac 並在通過Settings -> Security & Privacy啟用后運行。

我希望這對你有所幫助。 享受結果,喝杯茶,坐下來。

當我試圖用一個小應用程序進行測試時,我在我的程序腳本中看到,我正在使用 C: 驅動器中的圖像目錄來引用圖像,例如:

      xxx.setStyleSheet("background-image: url(C:\pictures\image1.jpg);"

而我應該確保圖像與我的 F: 驅動器中的項目文件位於同一文件夾中

因此,當我將圖像復制到 F: 驅動器中包含項目文件的同一文件夾時,我只使用了:

   xxx.setStyleSheet("background-image: url(image1.jpg;")

我把它改成這種格式后效果很好

我只將圖像復制到項目文件夾中,而沒有在我的代碼引用中使用該路徑,但之前使用 C: 目錄在我的代碼中引用它。 這就是它沒有按預期工作的原因。

所以在我的腳本中使用正確的路徑,我使用了這個命令:

     pyinstaller --windowed  --add-data "image1.jpg;." --add-data "image2.jpg;." --add-data "image3.jpg;." --icon=myLogo.ico myPythonFile.py

我在程序中使用的所有頭像和背景圖像都顯示在它們應該在應用程序中的區域中,並且也可以在應用程序部署到的其他計算機中看到。

請管理員允許。 我決定放下它,因為我或我明天可能需要它。 我看到的其他答案對我來說有點令人困惑和困難

嘿,我正在使用 pyinstaller --noconfirm --onefile --windowed --splash file.jpg file.py 命令添加圖像,因此在添加圖像時卡住了。 在此處輸入圖片說明

在此處輸入圖片說明

將圖像轉換為base64代碼

首先在單獨的代碼中使用同名庫將您的圖像轉換為 base64 代碼,並將結果保存在另一個 python 文件中,以便您可以將其導入到您的主 python 文件中。 這是必要的,否則在使用 pyinstaller 將 .py 轉換為 .exe 並在新位置缺少圖像時移動 exe 文件后,您將收到file not found錯誤。

import base64
pic = open('file.png', 'rb')
content = f'img = {base64.b64encode(pic.read())}\n'
pic.close()

with open('pic2str.py', 'w') as f:
    f.write(content) 

在你的主 python 文件中導入 base64 代碼

現在在你的主文件中導入變量,這樣你的主代碼中就不會使用你的圖像文件地址。

from pic2str import img

bg = base64.b64decode(img)
image = tk.PhotoImage(data=bg)
label = tk.Label(
    root,
    compound="center",
    text="Your Text",
    font=("Your Font", Your Font size),
    fg="Your Color",
    image=image)
label.pack(fill="both", expand=1)

現在,您可以獨立於使用的圖像使用轉換為 .exe 的文件。

無憂無慮。 我有同樣的問題,只是這樣做得到了答案......復制我所有的圖像並將它們粘貼到由pyinstaller創建的dist /和build /目錄中,問題就解決了。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM