我可以使用Python访问ImageMagick API吗?

bsk*_*1ch 46 python ctypes image-manipulation imagemagick

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

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

有没有办法直接使用ctypes和转换某种类型的API ?作为最后的手段,还有其他任何图书馆都有大量的ImageMagick图像编辑工具,我已经查看了吗?

Yau*_*ich 65

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

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

  • 工作错误/无问题
  • 定期维护和更新
  • 允许很好的客观Python

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

  • GraphicsMagick工具
  • PythonMagick - 第一次实现
  • PythonMagickWand/Achim Domma - 第一个Wand - 一个CDLL实现
  • PythonMagickWand/Ian Stevens
  • MagickFoo - 包含在python-magickwand中
  • Wand/Hong Minhee - 最新项目

现在Wand只是ImageMagick的一个(简化的)C API".. API是C编程语言和ImageMagick图像处理库之间的推荐接口.与MagickCore C API不同,MagickWand只使用几种不透明类型.可以使用访问器设置或获取重要的魔杖属性." (见项目主页)

因此,它已经是一个易于维护的简化界面.

  • 我远离想要的主要原因是:https://github.com/dahlia/wand/issues/312 (2认同)

fmw*_*w42 8

对于以下命令,这对我有用,可以从字母“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)
Run Code Online (Sandbox Code Playgroud)

  • `shell=True` 是灾难的根源。使用 `cmd = ["path/to/program", "arg1", "arg2", ...]` 代替 `cmd = "a single string with all args"` 并永久删除 `shell=True` 。 (2认同)

Mak*_*nko 6

我发现 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)
Run Code Online (Sandbox Code Playgroud)

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