从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。 (或者,decode
和 bytes
对象分开;但这很麻烦,因为您需要指定正确的编码。)
b
和引号不是值的一部分,它们只是 Python 的注释,用于消除 repr
版本的歧义。
我不确定您所说的repr version
是什么意思。但是当它有 b 和单引号时,我将如何获取返回的变量并在进一步的计算中使用它?以上是关于从Python中的imagemagick子进程读取输出[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Imagemagick / Shell /子进程NodeJS