Python: Open multiple images in default image viewer - python

I am using PIL to open a single image in the default image viewer:
from PIL import Image
img = Image.open('example.jpg')
img.show()
Does any Python module contain a function enabling opening multiple images in the current system's default image viewer? For instance when on OS X, Preview.app should open with the list of images in the sidebar. From the command line this is no problem at all:
$ open my_picture_number_*
Use case is that users should just be able to explore a few dozen images.

Use subprocess.run to run the operating system's default image viewing app. subprocess.run works a lot like a command line. You just need to know what the command is for the operating system you're on. For windows, "explorer" will do; for OS X, as you point out, it's "open." I'm not sure what it is for Linux, maybe "eog"?
So, your code would look like this:
import sys
import subprocess
def openImage(path):
imageViewerFromCommandLine = {'linux':'xdg-open',
'win32':'explorer',
'darwin':'open'}[sys.platform]
subprocess.run([imageViewerFromCommandLine, path])

I've tried to use #jgfoot's answer, which worked, but made my program hang after the viewer was launched. I've solved this issue by using subprocess.Popen instead, like this:
import sys
import subprocess
def openImage(path):
imageViewerFromCommandLine = {'linux':'xdg-open',
'win32':'explorer',
'darwin':'open'}[sys.platform]
subprocess.Popen([imageViewerFromCommandLine, path])

Related

open and show any file in python [duplicate]

This question already has answers here:
Open document with default OS application in Python, both in Windows and Mac OS
(17 answers)
Closed 8 years ago.
I'm wondering how to open files in programs such as Notepad and Picture Viewer depending on the extension the file has. I'm using Python 3.3 on Windows.
I've done some research and people have mentioned a module named Image, but when I try and import this module I get an ImportError.
Here's what I have so far:
def openFile():
fileName = listbox_1.get(ACTIVE)
if fileName.endswith(".jpg"):
fileName.open()
I will also have HTML and JSON files that I will need to open in Notepad.
On Windows you could use os.startfile() to open a file using default application:
import os
os.startfile(filename)
There is no shutil.open() that would do it cross-platform. The close approximation is webbrowser.open():
import webbrowser
webbrowser.open(filename)
that might use automatically open command on OS X, os.startfile() on Windows, xdg-open or similar on Linux.
If you want to run a specific application then you could use subprocess module e.g., Popen() allows to start a program without waiting for it to complete:
import subprocess
p = subprocess.Popen(["notepad.exe", fileName])
# ... do other things while notepad is running
returncode = p.wait() # wait for notepad to exit
There are many ways to use the subprocess module to run programs e.g., subprocess.check_call(command) blocks until the command finishes and raises an exception if the command finishes with a nonzero exit code.
Use this to open any file with the default program:
import os
def openFile():
fileName = listbox_1.get(ACTIVE)
os.system("start " + fileName)
If you really want to use a certain program, such as notepad, you can do it like this:
import os
def openFile():
fileName = listbox_1.get(ACTIVE)
os.system("notepad.exe " + fileName)
Also if you need some if checks before opening the file, feel free to add them. This only shows you how to open the file.
Expanding on FatalError's suggestion with an example.
One additional benefit of using subprocessing rather than os.system is that it uses the same syntax cross-platform (os.system on Windows requires a "start" at the beginning, whereas OS X requires an "open". Not a huge deal, but one less thing to remember).
Opening a file with subprocess.call.
All you need to do to launch a program is call subprocess.call() and pass in a list of arguments where the first is the path to the program, and the rest are additional arguments that you want to supply to the program you're launching.
For instance, to launch Notepad.exe
import subprocess
path_to_notepad = 'C:\\Windows\\System32\\notepad.exe'
path_to_file = 'C:\\Users\\Desktop\\hello.txt'
subprocess.call([path_to_notepad, path_to_file])
Passing multiple arguments and paths is equally as simple. Just add additional items to the list.
Launching with multiple arguments
This, for example, launches a JAR file using a specific copy of the Java runtime environment.
import subprocess
import os
current_path = os.getcwd()
subprocess.call([current_path + '/contents/home/bin/java', # Param 1
'-jar', #Param2
current_path + '/Whoo.jar']) #param3
Argument 1 targets the program I want to launch. Argument2 supplies an argument to that program telling it that it's going to run a JAR, and finally Argument3 tells the target program where to find the file to open.

Image.open doesn't show any results

I'm trying to display an image using python. I used the following code :
from PIL import Image
img = Image.open("pic.jpg")
img.show()
del img
I checked that everything was installed, and tried different options inside the Image.open part, yet nothing works. I don't even have an error (so other topics were irrelevant in my case).
I am new to python, so I have no idea how to debug this. My code just executes but nothing happens.
If you have an idea, I'll try. Thank you.
You can get some information to debug your Python by changing your code to the following:
from PIL import Image
import subprocess
import sys
# Print the full path of the Python interpreter you are using
print(sys.executable)
# Print the working directory that your program is running in
subprocess.run('pwd')
# Print directory listing
# WINDOWS VERSION: subprocess.run('DIR')
subprocess.run(['ls', '-l'])
# Open the image
img = Image.open("pic.jpg")
# Check image loaded and its size and type
print(img)
# Display image
img.show()
# Check program ran to completion
print('Done')

Getting rid of black console windows when running sympy through spyder

Whenever I try to display symbolic math in Spyder via the IPython console, several black console windows pop up and then disappear in quick succession. It prints the expression, but I'd like to know if there is a way to get rid of these windows. The windows have the title "C:\Program Files\MikTex 2.9..." if that helps.
It looks like someone already figured it out and posted a solution on GitHub. This is the link: https://github.com/sympy/sympy/issues/11882
It took me (as a novice) some time to figure out exactly what he did, so the following is just a more detailed explanation:
You first need to find the compatibility module in the sympy package. For me, it was located at "C:\Users\Lucas\Anaconda3\Lib\site-packages\sympy\core\compatibility.py". Next, you need to search (in the source code of that module) for the check_output function. The surrounding code should look something like:
# check_output() is new in Python 2.7
import os
try:
try:
from subprocess import check_output
Finally, you need to get rid of the last line, and replace it with the code found in the GitHub link. The resulting block should look like:
# check_output() is new in Python 2.7
import os
try:
try:
from subprocess import check_output as subprocess_check_output
def check_output(*args, **kwargs):
return subprocess_check_output(*args, **kwargs, creationflags=0x08000000) # CREATE_NO_WINDOW
It appears to me that he defines a function which takes the place of check_output, except that the argument to suppress the output windows is always fed in. Hope this helps anyone else having this problem, and I appreciate the fix from Adam on GitHub.
I submitted a pull request to fix this for good:
https://github.com/sympy/sympy/pull/12391

Closing an image after opening it with webbrowser.open (Python 2.7)

So basically I am trying to open an image and then close it after few seconds with time.sleep.
First I tried using
import Image
import time
myImage = Image.open("C:\\Users\\User\\Desktop\\image.jpg")
myImage.show()
time.sleep(5)
but this didn't work out well, since the image didn't even open because Windows Photo Viewer couldn't find the file. However when I use webbrowser.open like this
import webbrowser
webbrowser.open('C:\\Users\\User\\Desktop\\image.jpg')
webbrowser.close()
it successfully opens the file in Windows Photo Viewer, but closing doesn't seem to work. It gives me the following error:
AttributeError: 'module' object has no attribute 'close'
I've been searching for 2 days now with no working solution. The image is .jpg incase that matters. Also I don't want to change my default image viewer or modify things that other people who use this would have to modify as well. Using Python 2.7.
Any help would be very much appreciated!
This is my way to do it in windows_xp_sp3.
import os, time
pic=["C:\\19.jpg","C:\\20.jpg","C:\\21.jpg","C:\\22.jpg"]
for p in pic:
os.startfile(p)
time.sleep(3)
os.system("taskkill /IM rundll32.exe")
Or, try this:
import subprocess, time
pic=["C:\\19.jpg","C:\\20.jpg","C:\\21.jpg","C:\\22.jpg","C:\\23.jpg","C:\\24.jpg","C:\\25.jpg","C:\\26.jpg","C:\\27.jpg"]
for p in pic:
r=subprocess.Popen(p,shell=True)
time.sleep(3)
# r.kill() #It won't work, because "shell=True" is set.If you need to kill the "subprocess",just don't use it.
Like This:
import os,subprocess, time
pic=["C:\\19.jpg","C:\\20.jpg","C:\\21.jpg","C:\\22.jpg","C:\\23.jpg","C:\\24.jpg","C:\\25.jpg","C:\\26.jpg","C:\\27.jpg"]
for p in pic:
r=subprocess.Popen(["rundll32.exe","shimgvw.dll,ImageView_Fullscreen",p])
time.sleep(3)
r.kill()
You are on the wrong track here, to close it you would have to instruct the browser to close that tab, or window, or whatever.
The way to instruct a browser to do that, is not standardized, and the same holds for something which is different for each browser, or indeed for each photo viewer.
If you want to control both opening and closing of a photo, you are better off doing that from within your Python program, instead of calling upon a different program such as a browser.

Resize the terminal with Python?

I couldn't find anything with a quick Google search, nor anything on here, saving for this. However, it doesn't do the trick. So how exactly do you resize the terminal using Python?
To change the tty/pty setting you have to use an ioctl on the stdin file descriptor.
import termios
import struct
import fcntl
def set_winsize(fd, row, col, xpix=0, ypix=0):
winsize = struct.pack("HHHH", row, col, xpix, ypix)
fcntl.ioctl(fd, termios.TIOCSWINSZ, winsize)
But to change the actual window size you can use terminal escape sequences, but not all terminals support or enable that feature. If you're using urxvt you can do this:
import sys
sys.stdout.write("\x1b[8;{rows};{cols}t".format(rows=32, cols=100))
But that may not work on all terminals.
If you install xdotool, you can change the size of the terminal window with something like this:
import subprocess
import shlex
id_cmd='xdotool getactivewindow'
resize_cmd='xdotool windowsize --usehints {id} 100 30'
proc=subprocess.Popen(shlex.split(id_cmd),stdout=subprocess.PIPE)
windowid,err=proc.communicate()
proc=subprocess.Popen(shlex.split(resize_cmd.format(id=windowid)))
proc.communicate()
PS. On Ubuntu xdotool is provided by a package of the same name.

Categories