1

I am wanting to get the average brightness of a file in python. Having read a previous question [Problem getting terminal output from ImageMagick's compare.exe ( Either by pipe or Python ) I have come up with :

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

the previous question recommended the use of 'pythonmagick' which I can find but with no current documentation and very little recent activity. I could not work out the syntax to use it.

I know that my code is unsatisfactory but it does work. Is there a better way which does not need 'shell=true' or additional file processing ?

2

2 Answers 2

1

This seems to works for me to return the mean as a variable that can be printed. (This is a bit erroneous. See the correction near the bottom)

#!/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)


The result is 70.67860, which is returned to the terminal.

This also works with shell=False, if you parse each part of the command.

#!/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)


The result is 70.67860, which is returned to the terminal.

The comment from tripleee below indicates that my process above is not correct in that the mean is being shown at the terminal, but not actually put into the variable.

He suggested to use subprocess.check_output(). The following is his solution. (Thank you, tripleee)

#!/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)

Prints: mean=70.6786

Sign up to request clarification or add additional context in comments.

7 Comments

This doesn't capture the output in mean, it just gets printed on standard output before you try to print the value from Python. You want subprocess.check_output() or its modern replacement subprocess.run() instead of subprocess.call().
@tripleee. Thanks for the correction. I am a novice with Python. But I have posted a correction in my post with your solution.
Add universal_newlines=True to receive the output as a decoded string. The OS performs I/O on bytes buffers in Python 3 by default. (Alternatively, decode the bytes object separately; but that's a hassle because then you need to specify the correct encoding.)
The b and the quotes are not part of the value, they are just Python's annotations to disambiguate the repr version.
I am not sure what you mean by repr version. But how would I take the returned variable and use that in some further calculations when it has the b and single quotes?
|
0

You can probably improve the subprocess, and eliminate the temporary text file with 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 also ships with the identify utility. The same method could be achieved with...

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

It might be worth exploring if it's worth working directly with ImageMagick's shared libraries. Usually connected through C-API (pythonmagick, wand, &etc). For what your doing, this would only increase code-complexity, increase module dependancies, but in no way improve performance or accuracy.

1 Comment

There is no good reason to reimplement subprocess.check_output() or its modern replacement subprocess.run(). Generally avoid subprocess.Popen() unless you really know what you are doing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.