从Python中的imagemagick子进程读取输出[重复]

Posted

技术标签:

【中文标题】从Python中的imagemagick子进程读取输出[重复]【英文标题】:Reading output from imagemagick subprocess in Python [duplicate] 【发布时间】:2019-02-21 15:48:22 【问题描述】:

我想在 python 中获取文件的平均亮度。阅读了上一个问题 [Problem getting terminal output from ImageMagick's compare.exe ( Either by pipe or Python ) 我想出了:

cmd='/usr/bin/convert  -format "%[fx:100*image.mean]\n" info: >    bright.txt'.format(full)
subprocess.call(cmd,shell=True)
with open('bright.txt', 'r') as myfile:
    x=myfile.read().replace('\n', '')
return x

上一个问题推荐使用“pythonmagick”,我可以找到它,但没有当前文档,最近的活动也很少。我想不出使用它的语法。

我知道我的代码不能令人满意,但它确实有效。 有没有更好的方法不需要 'shell=true' 或额外的文件处理?

【问题讨论】:

我不是 Python Wand 专家,但您可以在 Python Wand 中执行 fx 命令。见docs.wand-py.org/en/0.4.1/wand/image.html 您还可以使用 Python Pillow 来获取图像的均值。见pillow.readthedocs.io/en/5.2.x/reference/ImageStat.html 【参考方案1】:

您可能可以改进子流程,并使用Popen + PIPE 消除临时文本文件。

cmd=['/usr/bin/convert',
     full,
     '-format',
     '%[fx:100*image.mean]',
     'info:']
pid = subprocess.Popen(cmd,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)
out, err = pid.communicate()
return float(out)

ImageMagick 还附带 identify 实用程序。同样的方法可以用...实现。

cmd=['/usr/bin/identify', '-format', '%[fx:100*image.mean]', full]

如果值得直接使用 ImageMagick 的共享库,可能值得探索。通常通过 C-API(pythonmagick、wand 等)连接。对于您所做的事情,这只会增加代码复杂性,增加模块依赖性,但绝不会提高性能或准确性。

【讨论】:

没有充分的理由重新实现subprocess.check_output() 或其现代替代品subprocess.run()。一般避免subprocess.Popen(),除非你真的知道自己在做什么。【参考方案2】:

这似乎对我有用,可以将平均值作为可以打印的变量返回。 (这有点错误。请参阅底部附近的更正)

#!/opt/local/bin/python3.6

import subprocess

cmd = '/usr/local/bin/convert lena.jpg -format "%[fx:100*mean]" info:'

mean=subprocess.call(cmd, shell=True)
print (mean)

结果是70.67860,返回到终端。

如果您解析命令的每个部分,这也适用于 shell=False。

#!/opt/local/bin/python3.6

import subprocess

cmd = ['/usr/local/bin/convert','lena.jpg','-format','%[fx:100*mean]','info:']

mean=subprocess.call(cmd, shell=False)
print (mean)

结果是70.67860,返回到终端。

下面tripleee的评论表明我上面的过程是不正确的,因为平均值显示在终端上,但实际上并没有放入变量中。

他建议使用subprocess.check_output()。以下是他的解决方案。 (谢谢你,三胞胎)

#!/opt/local/bin/python3.6

import subprocess

filename = 'lena.jpg'
mean=subprocess.check_output(
    ['/usr/local/bin/convert',
     filename,
     '-format',
     'mean=%[fx:100*mean]', 
     'info:'], universal_newlines=True)
print (mean)

打印:mean=70.6786

【讨论】:

这不会捕获mean 中的输出,它只是在您尝试print 来自Python 的值之前打印在标准输出上。您想要subprocess.check_output() 或其现代替代品subprocess.run() 而不是subprocess.call() @tripleee。感谢您的更正。我是 Python 的新手。但是我已经在我的帖子中发布了您的解决方案的更正。 添加universal_newlines=True 以接收作为解码字符串的输出。默认情况下,操作系统在 Python 3 中对 bytes 缓冲区执行 I/O。 (或者,decodebytes 对象分开;但这很麻烦,因为您需要指定正确的编码。) b 和引号不是值的一部分,它们只是 Python 的注释,用于消除 repr 版本的歧义。 我不确定您所说的repr version 是什么意思。但是当它有 b 和单引号时,我将如何获取返回的变量并在进一步的计算中使用它?

以上是关于从Python中的imagemagick子进程读取输出[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Imagemagick / Shell /子进程NodeJS

确定子进程是不是从标准输入读取

从 Python 调用带有“子进程”的 Java 应用程序并读取 Java 应用程序输出

使用python子进程和ssh读取远程文件?

python:在线程中读取子进程输出

Python子进程将数据定向到标准输入