How do I display and close an image with Python? - python

I would like to display an image with Python and close it after user enters the name of the image in terminal. I use PIL to display image, here is the code:
im = Image.open("image.jpg")
im.show()
My application display this image, but user task is to recognize object on image and write answer in terminal. If answer entered is correct user should get another image. Problem with PIL is that I can't close the image and with research the only solution was to kill the process of image viewer, but this is not really reliable and elegant.
Are there any other libraries for displaying images that have methods like .show() and .close() ?

Just open any image viewer/editor in a separate process and kill it once user has answered your question e.g.
from PIL import Image
import subprocess
p = subprocess.Popen(["display", "/tmp/test.png"])
raw_input("Give a name for image:")
p.kill()

A little late to the party, but (as a disgruntled data scientist who really can't be bothered to learn gui programming for the sake of displaying an image) I can probably speak for several other folks who would like to see an easier solution for this. I figured out a little work around by expanding Anurag's solution:
Make a second python script (let's call it 'imviewer.py'):
from skimage.viewer import ImageViewer
from skimage.io import imread
img = imread('image.png') #path to IMG
view = ImageViewer(img)
view.show()
Then in your main script do as Anurag suggested:
import subprocess
p = subprocess.Popen('python imviewer.py')
#your code
p.kill()
You can make the main script save the image you want to open with 'imviewer.py' temporarily, then overwrite it with the next image etc.
Hope this helps someone with this issue!

Terminal is meant to deal with linear command flow - meaning it asks a question, user answers, and then it can ask a different question. What you are trying to do here is for terminal to do two things, show an image and at the same time ask user a question. To do this you can do two of either things:
Multiprocessing
You can start a new thread/process and make PIL show the image using that thread, and meanwhile in the first thread/process ask a user a question. Then after the user answers, you can close the other thread/process. You can take a look at Python's threading module (link) for more information on how you can do that.
GUI
Instead of making your user interface in terminal, make a simple GUI application using whatever framework you are comfortable. I personally like PyQt4. Qt is very powerful GUI development toolkit and PyQt4 is a wrapper for it. If you make a GUI, then what you are tyring to do is rather trivial.

Not all GUIs are difficult to use.
Here is a single-line solution using PySimpleGUI. Normally I wouldn't write it as a single line, but since it's a one-off, perhaps doesn't need adding to, then it's OK to do.
import PySimpleGUI as sg
sg.Window('My window').Layout([[ sg.Image('PySimpleGUI.png') ]]).Read()

Might be an overkill, but for me the easiest and most robust solution was just to use matplotlib as it properly keeps track of the figures it creates, e.g. :
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
imgplot = plt.imshow(mpimg.imread('animal.png'))
plt.ion()
plt.show()
animal_name = raw_input("What is the name?: ")
plt.close()

Related

Stuck with catpcha solving in python

We are writing a very simple code for a game which automates an enhancing process (it's our own server so it's just for the fun of it) during this process you occasionally get a captcha which you have to solve in order to continue enhancing. We are stuck up on how we could solve the captchas and this is where we need your help. The code is written in python and is very simple. The captcha is also very simple it's only 3 numbers. (can't be anything else other than numbers from 0-9) Here is how the captcha window looks like: [https://i.stack.imgur.com/27mAK.png]
The code looks like this:
import pyautogui
import time
import keyboard
while True:
opt = pyautogui.locateOnScreen('asd.png', confidence=.95) #looks for a good enchant
forgat = pyautogui.locateOnScreen('forgatas.png') #locates the button to press for enhancing
stop = keyboard.is_pressed("shift") #stops the loop with shift
if opt:
print('Done')
break
if stop:
print('Stopped')
break
else:
pyautogui.click(forgat)
time.sleep(0.2)
Did some testing with pytesseract:
from cv2 import cv2
import pytesseract
import pyautogui
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
img = cv2.imread('ak.png')
text = pytesseract.image_to_string(img)
print(text)
It successfully converts the img to text but we can't figure out how to copy the text into the text-box in game. Copying the ingame text is not an option.
Would also like to ask you to give suggestions regarding speeding up the process while the locateOnScreen function is still able to keep up (don't want the code to skip over a good enchant for going too fast) and maybe using something else instead of time.sleep because it heavily taxes the system. Sorry if the code is messy we are still very much beginners and we never learned python before. Any help would be greatly appricated! Looking forward to any suggestion!
I suggest you to try this library I've found some time ago. If you have a set of labelled captchas that service would fit you. Take a look: https://github.com/punkerpunker/captcha_solver
In README there is a section "Train model on external data" that you might be interested in.

Opening an image using basic python commands

So I'm creating a basic program that lets you play roulette for a Computer Science Class. The program is fully built, I just had a question regarding images in Python. Is is possible to have my program display an image when prompted to by an if statement? I'm fairly new to python, any help would be appreciated.
from PIL import Image
image = Image.open('path_to_image')
image.load()
Here is a tutorial on how to use Pil(low), a Python Image Library: How to use Pillow
Edit: You are probably building a GUI for you game, so check out TKinter, it's Graphical User Interface Library, with this you can create the "windows" of your game and place images and buttons there.
Use Python Image Library(PIL), it's pretty easy and has tons of documentation.

adding a quit timer that closes a photo

After many hours of searching online and in my python book I can't seem to find the answer to my question which is what do I add to my code so I can put in a timer that automatically closes the photo? It pulls itself up but then I have to manually close the photo to get back to my main program. Any help would be appreciated.
from PIL import Image
img = Image.open('battleship load screen.png')
img.show()
This is not possible using PIL alone - img.show() is just launching another program, it's intended for debugging really, not for presenting things to the user.
From the docs.
Displays an image. This method is mainly intended for debugging
purposes.
On Unix platforms, this method saves the image to a temporary PPM
file, and calls the xv utility.
On Windows, it saves the image to a temporary BMP file, and uses the
standard BMP display utility to show it.
This method returns None.
If you want to display an image and have control over it, use a graphical toolkit and construct a UI for your purpose. I've linked there to an example using PySide, a set of QT bindings, but of course you could use any toolkit - each will be different.

How to display an image with Pylab from a script in a non blocking way

I am writing some iterative image processing algorithm in a script (I don't want to be using iPython), and I would like to visualize the image I generate after each iteration. That's very easy to do in Matlab, without blocking the main thread, but I am struggling to do it in Python.
In pylab the show() function is blocking and I need to close the window to continue the execution of my script. I have seen that some people use the ion() function, but it has no effect in my case, for example:
pylab.ion()
img = pylab.imread('image.png')
pylab.imshow(img)
pylab.show()
is still blocking. I also saw people saying that "using draw instead of plot" can solve this. However, I am not using plot but imshow/show, is there something that I am missing here?
On the other hand, the PIL also has some display functions, but it seems to generate a temporary image and then display it with imagemagick, so I assume there is no way here to display an image and update it in the same window with this method.
I am using Ubuntu 10.10.
Does anyone know how to do it simply, or do I have to start using something like Qt to have a minimal GUI that I can update easily?
Try using pylab.draw() instead of pylab.show().
pylab.show() will start a Tk mainloop, hence it is blocking. Whereas pylab.draw() will force a draw of figure at that point. Since you are using pylab.ion(), figures are created already. But at the end of the script you have to put a pylab.show() otherwise figures will be closed when script finishes as there is no mainloop. One side effect is that, you can't interact with the figures until you reach pylab.show().
you can try to thread your pylab stuff :
import pylab
import threading
pylab.ion()
img = pylab.imread('map.png')
def create_show():
pylab.imshow(img)
pylab.show()
thread = threading.Thread(target=create_show)
thread.start()
#do your stuff
thread.join()

Taking screenshot from a python script by selecting the area

I saw that post (that is really helpful : Take a screenshot via a python script. [Linux]) about taking a screenshot from python. It works well but I'd like to have the same behavior as gnome-screenshot : having the possibility to choose between :
Capturing the whole desktop
Capturing an active window
Capturing an area
Is there a way to do this in python, or, eventually, to use the gnome-screenshot application to do it, and then getting the file ?
I tried to find the perfect command line for gnome-screenshot to be launched without asking where to save the screenshot after by giving the path at the call, but I can't find it.
Thanks for your help!
I have a wrapper project (pyscreenshot) for scrot, imagemagick, pyqt, wx and pygtk.
If you have one of them, you can use it.
Capturing an active window is missing.
Install:
easy_install pyscreenshot
Example:
import pyscreenshot as ImageGrab
# fullscreen
im=ImageGrab.grab()
im.show()
# part of the screen
im=ImageGrab.grab(bbox=(10,10,500,500))
im.show()
# to file
ImageGrab.grab_to_file('im.png')
If you are not limited to using using gnome-screenshot specifically, ImageMagick's import command can save directly to file without an interactive prompt.
See here for details: http://www.imagemagick.org/script/import.php
In addition to the command line interface, there is also a Python API.

Categories

Resources