【问题标题】:Can I access ImageMagick API with Python?我可以使用 Python 访问 ImageMagick API 吗?
【发布时间】:2011-12-15 06:25:26
【问题描述】:

我需要使用ImageMagick,因为 PIL 没有我正在寻找的大量图像功能。但是,我想使用 Python。

python 绑定 (PythonMagick) 自 2009 年以来一直没有更新。我唯一能找到的是 os.system 调用以使用命令行界面,但这似乎很笨重。

有没有办法直接使用ctypes 和某种转换来访问 API? 作为最后的手段,是否有任何其他库拥有大量图像编辑工具,例如我看过的 ImageMagick?

【问题讨论】:

    标签: python imagemagick image-manipulation ctypes


    【解决方案1】:

    我建议使用Wand(解释如下)。

    我正在寻找与 ImageMagick 库的正确绑定,这将:

    • 工作错误/无问题
    • 定期维护和更新
    • 允许漂亮的目标 Python

    但确实 python API(绑定)有太多不同的(大部分已停产)版本。阅读 Benjamin Schweizer 的精彩历史概述后,一切都变得清晰(另见他的github wiki

    • GraphicsMagick
    • PythonMagick - 第一个实现
    • PythonMagickWand/Achim Domma - 第一个 Wand - CDLL 实现
    • PythonMagickWand/伊恩·史蒂文斯
    • MagickFoo - 包含在 python-magickwand 中
    • Wand/Hong Minhee - 最新项目

    现在 Wand 只是 ImageMagick 的(简化的)C API “.. API 是 C 编程语言和 ImageMagick 图像处理库之间的推荐接口。与 MagickCore C API 不同,MagickWand 仅使用少数不透明类型。访问器可用于设置或获取重要的魔杖属性。” (See project homepage)

    所以它已经是一个更易于维护的简化界面了。

    【讨论】:

    【解决方案2】:

    这对我来说适用于以下命令,可以从文本中为字母“P”创建图像:

    import subprocess
    
    cmd = '/usr/local/bin/convert -size 30x40 xc:white -fill white -fill black -font Arial -pointsize 40 -gravity South -draw "text 0,0 \'P\'" /Users/fred/desktop/draw_text2.gif'
    
    subprocess.call(cmd, shell=True)
    

    【讨论】:

    • shell=True 是灾难的根源。而不是 cmd = "a single string with all args" 使用 cmd = ["path/to/program", "arg1", "arg2", ...] 并永久删除 shell=True
    • 为什么这是一个问题——注入问题?
    • 是的,注入是主要问题(Python 的手册甚至明确地警告了这一点)(但是,注入可能是偶然发生的,而不是出于恶意)。但是你也会让你的脚本更加依赖于它的环境/操作系统(例如,Linux shell 的引用机制与 Windows cmd 不同),
    【解决方案3】:

    我发现 ImageMagick 没有好的 Python 绑定,所以为了在 Python 程序中使用 ImageMagick,我必须使用 subprocess 模块来重定向输入/输出。

    例如,假设我们需要将 PDF 文件转换为 TIF:

    path = "/path/to/some.pdf"
    cmd = ["convert", "-monochrome", "-compress", "lzw", path, "tif:-"]
    fconvert = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = fconvert.communicate()
    assert fconvert.returncode == 0, stderr
    
    # now stdout is TIF image. let's load it with OpenCV
    filebytes = numpy.asarray(bytearray(stdout), dtype=numpy.uint8)
    image = cv2.imdecode(filebytes, cv2.IMREAD_GRAYSCALE)
    

    在这里,我使用tif:- 告诉 ImageMagick 的命令行实用程序我想将 TIF 图像作为标准输出流。以类似的方式,您可以通过指定- 作为输入文件名来告诉它使用标准输入流作为输入。

    【讨论】:

      猜你喜欢
      • 2016-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2020-11-02
      • 2011-03-03
      • 1970-01-01
      相关资源
      最近更新 更多