You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Windows下如何用PyInstaller打包Ghostscript至Python工具解决转换报错?

解决方案:将Ghostscript嵌入PyInstaller打包程序

针对你遇到的OSError: Unable to locate Ghostscript on paths问题,这里有几个实用的方法,能让你的同事无需单独安装Ghostscript就能运行工具:

方法1:嵌入便携版Ghostscript并在代码中指定路径

这个方法最直接,把Ghostscript的便携二进制文件打包进程序,再告诉PIL它的位置:

  1. 下载适配的便携版Ghostscript
    下载Windows便携版Ghostscript(注意要和你的Python版本匹配32位/64位),解压后放到项目目录的指定文件夹,比如新建vendor/ghostscript,把解压后的所有文件(包括gswin64c.exegswin32c.exe和依赖文件)放进去。

  2. 修改代码,指定Ghostscript路径
    在程序初始化或者save_as_png函数开头,添加这段代码来动态设置路径:

    import os
    import sys
    from PIL import EpsImagePlugin
    
    def get_ghostscript_path():
        # 判断是否是PyInstaller打包后的运行环境
        if hasattr(sys, '_MEIPASS'):
            # 打包后临时目录下的ghostscript路径
            return os.path.join(sys._MEIPASS, 'vendor', 'ghostscript', 'gswin64c.exe')
        else:
            # 开发环境下的本地路径
            return os.path.join(os.path.dirname(__file__), 'vendor', 'ghostscript', 'gswin64c.exe')
    
    # 给PIL指定Ghostscript的位置
    EpsImagePlugin.gs_windows_binary = get_ghostscript_path()
    

    备注:如果是32位版本,把gswin64c.exe替换成gswin32c.exe

  3. PyInstaller打包时包含Ghostscript文件
    用命令行打包时添加资源包含参数:

    pyinstaller --onefile --add-data "vendor/ghostscript;vendor/ghostscript" your_main_script.py
    

    或者编写spec文件,在datas字段中添加资源路径:

    a = Analysis(
        ['your_main_script.py'],
        datas=[('vendor/ghostscript', 'vendor/ghostscript')],
        # 其他打包配置...
    )
    

    然后执行pyinstaller your_script.spec完成打包。

方法2:绕过PostScript直接保存画布为PNG

如果不想折腾Ghostscript,也可以直接将tkinter画布内容转成PNG,跳过PS中间步骤:

from PIL import Image, ImageDraw
import tkinter as tk

def save_canvas_to_png(canvas, save_path):
    # 获取画布尺寸
    w, h = canvas.winfo_width(), canvas.winfo_height()
    # 创建空白白底图像
    img = Image.new('RGB', (w, h), 'white')
    draw = ImageDraw.Draw(img)

    # 遍历画布元素并绘制到图像上(需根据你的元素类型补充逻辑)
    for item in canvas.find_all():
        item_type = canvas.type(item)
        # 示例:处理线条
        if item_type == 'line':
            coords = canvas.coords(item)
            fill = canvas.itemcget(item, 'fill')
            line_width = int(canvas.itemcget(item, 'width'))
            draw.line(coords, fill=fill, width=line_width)
        # 示例:处理矩形
        elif item_type == 'rectangle':
            coords = canvas.coords(item)
            fill = canvas.itemcget(item, 'fill')
            outline = canvas.itemcget(item, 'outline')
            draw.rectangle(coords, fill=fill, outline=outline)
        # 其他元素(文本、椭圆等)同理补充处理逻辑

    # 保存图像
    img.save(save_path, 'PNG')

这个方法适合画布元素类型较少的场景,如果你的画布内容复杂,还是用Ghostscript嵌入的方法更省心。

关键注意事项

  • 必须下载和Python打包版本(32/64位)匹配的Ghostscript,否则会出现运行错误。
  • 便携版Ghostscript无需安装,解压后直接使用,打包后同事运行时没有额外安装步骤。

你的报错信息:
Exception in Tkinter callback
Traceback (most recent call last):
File "tkinter_init_.py", line 1705, in call
File "user_input.py", line 49, in save_as
File "drawing_func.py", line 1232, in save_as_png
File "site-packages\PIL\Image.py", line 1973, in save
File "site-packages\PIL\Image.py", line 628, in _ensure_mutable
File "site-packages\PIL\Image.py", line 621, in _copy
File "site-packages\PIL\EpsImagePlugin.py", line 333, in load
File "site-packages\PIL\EpsImagePlugin.py", line 139, in Ghostscript
OSError: Unable to locate Ghostscript on paths

内容的提问来源于stack exchange,提问作者Anas AG

火山引擎 最新活动