What is the easiest way to show a .jpg or .gif image from Python console?
I've got a Python console program that is checking a data set which contains links to images stored locally. How should I write the script so that it would display images pop-up graphical windows?
Using the awesome Pillow library:
>>> from PIL import Image
>>> img = Image.open('test.png')
>>> img.show()
This will open the image in your default image viewer.
In a new window using Pillow/PIL
Install Pillow (or PIL), e.g.:
$ pip install pillow
Now you can
from PIL import Image
with Image.open('path/to/file.jpg') as img:
img.show()
Using native apps
Other common alternatives include running xdg-open or starting the browser with the image path:
import webbrowser
webbrowser.open('path/to/file.jpg')
Inline a Linux console
If you really want to show the image inline in the console and not as a new window, you may do that but only in a Linux console using fbi see ask Ubuntu or else use ASCII-art like CACA.
Since you are probably running Windows (from looking at your tags), this would be the easiest way to open and show an image file from the console without installing extra stuff like PIL.
import os
os.system('start pic.png')
Or simply execute the image through the shell, as in
import subprocess
subprocess.call([ fname ], shell=True)
and whatever program is installed to handle images will be launched.
In Xterm-compatible terminals, you can show the image directly in the terminal. See my answer to "PPM image to ASCII art in Python"
If you would like to show it in a new window, you could use Tkinter + PIL library, like so:
import tkinter as tk
from PIL import ImageTk, Image
def show_imge(path):
image_window = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(image_window, image=img)
panel.pack(side="bottom", fill="both", expand="yes")
image_window.mainloop()
This is a modified example that can be found all over the web.
Why not just display it in the user's web browser?
You cannot display images in a console window.
You need a graphical toolkit such as Tkinter, PyGTK, PyQt, PyKDE, wxPython, PyObjC, or PyFLTK.
There are plenty of tutorials on how to create simple windows and loading images in python.
You can also using the Python module Ipython, which in addition to displaying an image in the Spyder console can embed images in Jupyter notebook. In Spyder, the image will be displayed in full size, not scaled to fit the console.
from IPython.display import Image, display
display(Image(filename="mypic.png"))
I made a simple tool that will display an image given a filename or image object or url.
It's crude, but it'll do in a hurry.
Installation:
$ pip install simple-imshow
Usage:
from simshow import simshow
simshow('some_local_file.jpg') # display from local file
simshow('http://mathandy.com/escher_sphere.png') # display from url
If you want to open the image in your native image viewer, try os.startfile:
import os
os.startfile('file')
Or you could set the image as the background using a GUI library and then show it when you want to. But this way uses a lot more code and might impact the time your script takes to run. But it does allow you to customize the ui. Here's an example using wxpython:
import wx
########################################################################
class MainPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
self.SetBackgroundStyle(wx.BG_STYLE_PAINT) # Was wx.BG_STYLE_CUSTOM)
self.frame = parent
sizer = wx.BoxSizer(wx.VERTICAL)
hSizer = wx.BoxSizer(wx.HORIZONTAL)
for num in range(4):
label = "Button %s" % num
btn = wx.Button(self, label=label)
sizer.Add(btn, 0, wx.ALL, 5)
hSizer.Add((1,1), 1, wx.EXPAND)
hSizer.Add(sizer, 0, wx.TOP, 100)
hSizer.Add((1,1), 0, wx.ALL, 75)
self.SetSizer(hSizer)
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
#----------------------------------------------------------------------
def OnEraseBackground(self, evt):
"""
Add a picture to the background
"""
# yanked from ColourDB.py
dc = evt.GetDC()
if not dc:
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.Clear()
bmp = wx.Bitmap("file")
dc.DrawBitmap(bmp, 0, 0)
########################################################################
class MainFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, size=(600,450))
panel = MainPanel(self)
self.Center()
########################################################################
class Main(wx.App):
""""""
#----------------------------------------------------------------------
def __init__(self, redirect=False, filename=None):
"""Constructor"""
wx.App.__init__(self, redirect, filename)
dlg = MainFrame()
dlg.Show()
#----------------------------------------------------------------------
if __name__ == "__main__":
app = Main()
app.MainLoop()
(source code from how to put a image as a background in wxpython)
You can even show the image in your terminal using timg:
import timg
obj = timg.Renderer()
obj.load_image_from_file("file")
obj.render(timg.SixelMethod)
(PyPI: https://pypi.org/project/timg)
You can use the following code:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
%matplotlib inline
img = mpimg.imread('FILEPATH/FILENAME.jpg')
imgplot = plt.imshow(img)
plt.axis('off')
plt.show()
Displaying images in console using Python
For this you will need a library called ascii_magic
Installation : pip install ascii_magic
Sample Code :
import ascii_magic
img = ascii_magic.from_image_file("Image.png")
result = ascii_magic.to_terminal(img)
Reference : Ascii_Magic
2022:
import os
os.open("filename.png")
It will open the filename.png in a window using default image viewer.
The easiest way to display an image from a console script is to open it in a web browser using webbrowser standard library module.
No additional packages need to be installed
Works across different operating systems
On macOS, webbrowser directly opens Preview app if you pass it an image file
Here is an example, tested on macOS.
import webbrowser
# Generate PNG file
path = Path("/tmp/test-image.png")
with open(path, "wb") as out:
out.write(png_data)
# Test the image on a local screen
# using a web browser.
# Path URL format may vary across different operating systems,
# consult Python manual for details.
webbrowser.open(f"file://{path.as_posix()}")
Related
I'm new to python and I don't know much yet. So, I wanted to convert my python project to an exe file, and so I followed the steps like in every youtube tutorial, terminal, pyinstaller and stuff (I use Pychram), but soon I realized that the icon I set for my exe isn't loading unless it's in the same folder as dist and .spec file. I decided to search some, I found a way on this site: https://clay-atlas.com/us/blog/2020/11/04/python-en-package-pyinstaller-picture/ (3rd method), but i was unable to decode it, I just need to replace something with my filename but I don't understand where exactly, like is pic2str a variable or a project name? Thanks.
(Code might be slightly shifted in here copy from the website if you need)
import base64
def pic2str(file, functionName):
pic = open(file, 'rb')
content = '{} = {}\n'.format(functionName, base64.b64encode(pic.read()))
pic.close()
with open('pic2str.py', 'a') as f:
f.write(content)
if __name__ == '__main__':
pic2str('test.png', 'explode')
And this:
import sys
import base64
from io import BytesIO
from PyQt5 import QtWidgets
from PyQt5.QtGui import *
from test import Ui_MainWindow
from PIL import Image, ImageQt
from pic2str import explode
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Load byte data
byte_data = base64.b64decode(explode)
image_data = BytesIO(byte_data)
image = Image.open(image_data)
# PIL to QPixmap
qImage = ImageQt.ImageQt(image)
image = QPixmap.fromImage(qImage)
# QPixmap to QLabel
self.ui.label.setPixmap(image)
self.ui.label.setScaledContents(True)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())
I found a solution,
you just have to use
--onefile
so the .exe file doesn't require any connection to the folder, and use
--icon insertpicturename.ico
to make the file have the icon you need, you can convert an image to .ico using online converters. And, I would also recommend using
--noconsole
if it fits your needs, it just removes the console showing up before opening the file.
you can try auto-py-to-exe, its a convenient little script that will allow you to use pyinstaller from a GUI and it will create the required terminal command for you. you can get it using pip install auto-py-to-exe and launch it from your terminal with the command auto-py-to-exe, you will see a section called Icon where you can open a .ico file through a file broswer window
I am doing GUI programming using Tkinter on Python. I am using the grid manager to make widgets. I have created several buttons and I want to upload an image on top of them. When I enter this code, it gives me an escape sequence error.
I heard using PIL is not a good idea? Is that true?
cookImage = PhotoImage(file = "image/C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Windows filenames must be entered as raw strings:
cookImage = PhotoImage(file=r"C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
This applies to all of Python, not just PIL.
Use:
path = r"a string with the path of the photo"
Note the r prefix, it means a raw string.
...
img = ImageTk.PhotoImage(Image.open(file=path))
label = tk.Label(root, image = img)
label.something() #pack/grid/place
...
The path can be:
Absolute ("C:\Users\terimaa\AppData\Local\Programs\Python\Python36-32\cook.gif")
Relative ("\cook.gif", depends on where the Python code is)
If you have an image file that is exactly what you want, just open it with BitmapImage or PhotoImage. Note that Tcl/Tk 8.6, which you should have with 3.6 on Windows, also reads .png files. On Windows, prefix the filename with 'r' or use forward slashes: 'C:/User/...'.
The actual PIL package is no longer maintained and only works on 2.x. That is what a new user should not use. The compatible successor, pillow (installed for instance with python -m pip install pillow) is actively maintained and works with 3.x. The compatibility extends to the import statement: import PIL imports pillow. Pillows allows one to manipulate images and to convert many formats to tk format (the ImageTk class).
this is exact code which is most help for move image
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
import os, shutil
class Root(Tk):
def __init__(self):
super(Root,self).__init__()
self.title("thinter Dialog Widget")
self.minsize(640,400)
self.labelFrame = ttk.LabelFrame(self,text="Open A File")
self.labelFrame.grid(column=0,row=1,padx= 20, pady= 20)
self.btton()
def btton(self):
self.button = ttk.Button(self.labelFrame, text="Browse Afile", command=self.fileDailog)
self.button.grid(column=1,row=1)
def fileDailog(self):
self.fileName = filedialog.askopenfilename(initialdir = "/", title="Select A File",filetype=(("jpeg","*.jpg"),("png","*.png")))
self.label = ttk.Label(self.labelFrame, text="")
self.label.grid(column =1,row = 2)
self.label.configure(text = self.fileName)
os.chdir('e:\\')
os.system('mkdir BACKUP')
shutil.move(self.fileName,'e:\\')
if __name__ == '__main__':
root = Root()
root.mainloop()
you could not move image to c drive due to Permission denied: this code work successfully on python 3.8, 3,7
Am trying to display image in text control but it display only binary characters.
But is their any way I can archive this or its impossible dream to do it in wxpython
Please help I will need this agently.
Thank you advance
Here are the source codes that I have so far
import wx
class MainFrame(wx.Frame):
def __init__(self,*args,**kwargs):
super(MainFrame,self).__init__(*args,**kwargs)
self.main_panel = MainPanel(self,-1)
class MainPanel(wx.Panel):
def __init__(self,*args,**kwargs):
super(MainPanel,self).__init__(*args,**kwargs)
img1 = wx.Image("coins.png", wx.BITMAP_TYPE_ANY)
w = img1.GetWidth()
h = img1.GetHeight()
img1 = img1.Scale(w/2, h/2)
sb1 = wx.StaticBitmap(self, -1, wx.BitmapFromImage(img1))
self.txtctrl = wx.TextCtrl(self,-1,"display image here",size=(500,300),pos=(20,10))
class App(wx.App):
def OnInit(self):
mainframe = MainFrame(None,-1,title="Display image in txt ctrl",size=(600,400))
mainframe.Show()
mainframe.Center()
return True
if __name__ == "__main__":
app = App();
app.MainLoop()
You cannot put an image directly inside a regular wx.TextCtrl widget. That is currently impossible as they just don't support that. However, you can put an image into a RichTextCtrl widget. If you haven't downloaded it yet, be sure to get the wxPython demo from the project's website as it has a good example. Here are a couple links:
http://wxpython.org/Phoenix/docs/html/richtext.RichTextCtrl.html
http://play.pixelblaster.ro/blog/archive/2008/10/08/richtext-control-with-wxpython-saving-and-loading
If you just want to put an image in your application, then wx.Image is your friend (as John already mentioned).
You can do it with wx.Image read this
you can also see a more complex example here
I have written this simple script in python:
import gtk
window = gtk.Window()
window.set_size_request(800, 700)
window.show()
gtk.main()
now I want to load in this window an image from web ( and not from my PC ) like this:
http://www.dailygalaxy.com/photos/uncategorized/2007/05/05/planet_x.jpg
How can I do that ?
P.S. I don't want download the image ! I just want load the image from the URL.
This downloads the image from a url, but writes the data into a gtk.gdk.Pixbuf instead of to a file:
import pygtk
pygtk.require('2.0')
import gtk
import urllib2
class MainWin:
def destroy(self, widget, data=None):
print "destroy signal occurred"
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("destroy", self.destroy)
self.window.set_border_width(10)
self.image=gtk.Image()
response=urllib2.urlopen(
'http://www.dailygalaxy.com/photos/uncategorized/2007/05/05/planet_x.jpg')
loader=gtk.gdk.PixbufLoader()
loader.write(response.read())
loader.close()
self.image.set_from_pixbuf(loader.get_pixbuf())
# This does the same thing, but by saving to a file
# fname='/tmp/planet_x.jpg'
# with open(fname,'w') as f:
# f.write(response.read())
# self.image.set_from_file(fname)
self.window.add(self.image)
self.image.show()
self.window.show()
def main(self):
gtk.main()
if __name__ == "__main__":
MainWin().main()
Download the image. Google on how to download files with python, there are easy-to-use libraries for that.
Load the image into a widget. Look up how to display an image in GTK.
Sorry for the lack of detail, but the answer would get long and you'd still be better off reading on those subjects somewhere else.
Hope it helps!
Here's a simple script using WebKit:
#!/usr/bin/env python
import gtk
import webkit
window = gtk.Window()
window.set_size_request(800, 700)
webview = webkit.WebView()
window.add(webview)
window.show_all()
webview.load_uri('http://www.dailygalaxy.com/photos/uncategorized/2007/05/05/planet_x.jpg')
gtk.main()
Take note, though, that this does in fact download the image.
In GTK, how can I scale an image? Right now I load images with PIL and scale them beforehand, but is there a way to do it with GTK?
Load the image from a file using gtk.gdk.Pixbuf for that:
import gtk
pixbuf = gtk.gdk.pixbuf_new_from_file('/path/to/the/image.png')
then scale it:
pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
Then, if you want use it in a gtk.Image, crate the widget and set the image from the pixbuf.
image = gtk.Image()
image.set_from_pixbuf(pixbuf)
Or maybe in a direct way:
image = gtk.image_new_from_pixbuf(pixbuf)
It might be more effective to simply scale them before loading. I especially think so since I use these functions to load in 96x96 thumbnails from sometimes very large JPEGs, still very fast.
gtk.gdk.pixbuf_new_from_file_at_scale(..)
gtk.gdk.pixbuf_new_from_file_at_size(..)
Scale image from URL. ( scale reference )
import pygtk
pygtk.require('2.0')
import gtk
import urllib2
class MainWin:
def destroy(self, widget, data=None):
print "destroy signal occurred"
gtk.main_quit()
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("destroy", self.destroy)
self.window.set_border_width(10)
self.image=gtk.Image()
self.response=urllib2.urlopen(
'http://192.168.1.11/video/1024x768.jpeg')
self.loader=gtk.gdk.PixbufLoader()
self.loader.set_size(200, 100)
#### works but throwing: glib.GError: Unrecognized image file format
self.loader.write(self.response.read())
self.loader.close()
self.image.set_from_pixbuf(self.loader.get_pixbuf())
self.window.add(self.image)
self.image.show()
self.window.show()
def main(self):
gtk.main()
if __name__ == "__main__":
MainWin().main()
*EDIT: (work out fix) *
try:
self.loader=gtk.gdk.PixbufLoader()
self.loader.set_size(200, 100)
# ignore tihs:
# glib.GError: Unrecognized image file format
self.loader.write(self.response.read())
self.loader.close()
self.image.set_from_pixbuf(self.loader.get_pixbuf())
except Exception, err:
print err
pass
Just FYI, here is a solution which scales the image based on window size (Implying you are implementing this in a class which extends GtkWindow).
let [width, height] = this.get_size(); // Get size of GtkWindow
this._image = new GtkImage();
let pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(filePath,width,height,true);
this._image.set_from_pixbuf(pixbuf);
anyone doing this in C. This is how it's done
//Assuming you already loaded the file and saved the filename
//GTK_IMAGE(image) is the container used to display the image
GdkPixbuf *pb;
pb = gdk_pixbuf_new_from_file(file_name, NULL);
pb = gdk_pixbuf_scale_simple(pb,700,700,GDK_INTERP_BILINEAR);
gtk_image_set_from_pixbuf(GTK_IMAGE(image), pb);
actually when we use
gdk_pixbuf_scale_simple(pb,700,700,GDK_INTERP_BILINEAR); this function causes memory leakage (If we monitor task manager the memory requirement goes on increasing till it kills the process) when used with a timer event. How to solve that