Quickest way to preview a PIL image - python

I'm now working with PIL images in Python. What's the quickest way to preview a PIL image in the Python shell? Saving to a file and then opening it in my OS is pretty cumbersome.

The Image class has a show(self, title=None, command=None) method, which you can use.

After installing iPython and PyQT, you can display PIL images inline in ipython qtconsole after executing the following code:
# display_pil.py
# source: http://mail.scipy.org/pipermail/ipython-user/2012-March/009706.html
# by 'MinRK'
import Image
from IPython.core import display
from io import BytesIO
def display_pil_image(im):
"""displayhook function for PIL Images, rendered as PNG"""
b = BytesIO()
im.save(b, format='png')
data = b.getvalue()
ip_img = display.Image(data=data, format='png', embed=True)
return ip_img._repr_png_()
# register display func with PNG formatter:
png_formatter = get_ipython().display_formatter.formatters['image/png']
png_formatter.for_type(Image.Image, display_pil_image)
Example of usage:
import Image
import display_pil
im = Image.open('test.png')
im
ipython qtconsole will display the loaded image inline.

I would recommend to use iPython rather than the vanilla python interpreter. Then you can use matplotlib.pyplot.imshow function with ease, and with the Qt console you can even get the images plotted inline in the interpreter.

Related

Why do I get tkinter.TclError: bitmap not defined error?

from tkinter import *
from configparser import ConfigParser
from tkinter import messagebox
import requests
if weather:
location_lbl['text'] = '{}, {}'.format(weather[0], weather[1])
image_lbl['bitmap'] = 'icons/{}.png'.format(weather[4])
temp_lbl['text'] = '{:.2f}°C, {:.2f}°F'.format(weather[2], weather[3])
weather_lbl['text'] = weather[5]
I got this error:
_tkinter.TclError: bitmap "icons/50d.png" not defined
Please help me.
This is a misunderstanding, image_lbl['bitmap'] is NOT used for showing png files or your loaded image files, its more like for showing the bitmaps loaded into tkinter:
image_lbl['bitmap'] = 'error' #or questionhead, warning, gray50, etc.
If you want to load a png image then use tk.PhotoImage, like:
img = tk.PhotoImage(file='icons/{}.png'.format(weather[4]))
image_lbl['image'] = img
Though its worth noting that for using jpeg, an additional module named PIL has to be used.
Take a look at these, helpful links:
Bitmaps on tkinter
PhotoImage on tkinter

Make a GIF play exactly once with Python Wand

I can create an animated GIF like this:
from wand.image import Image
with Image() as im:
while i_need_to_add_more_frames():
im.sequence.append(Image(blob=get_frame_data(), format='png'))
with im.sequence[-1] as frame:
frame.delay = calculate_how_long_this_frame_should_be_visible()
im.type = 'optimize'
im.format = 'gif'
do_something_with(im.make_blob())
However, an image created like this loops indefinitely. This time, I want it to loop once, and then stop. I know that I could use convert's -loop parameter if I were using the commandline interface. However, I was unable to find how to do this using the Wand API.
What method should I call, or what field should I set, to make the generated GIF loop exactly once?
You'll need to use ctypes to bind the wand library to the correct C-API method.
Luckily this is straightforward.
import ctypes
from wand.image import Image
from wand.api import library
# Tell Python about the C-API method.
library.MagickSetImageIterations.argtypes = (ctypes.c_void_p, ctypes.c_size_t)
with Image() as im:
while i_need_to_add_more_frames():
im.sequence.append(Image(blob=get_frame_data(), format='png'))
with im.sequence[-1] as frame:
frame.delay = calculate_how_long_this_frame_should_be_visible()
im.type = 'optimize'
im.format = 'gif'
# Set the total iterations of the animation.
library.MagickSetImageIterations(im.wand, 1)
do_something_with(im.make_blob())

Image in TreeView not showing Tkinter

I am making a TreeView in Tkinter Python 3.4 I have added a chrome logo but the image never appears.
treeview=ttk.Treeview(frame3)
chromelogo=PhotoImage(file="./Images/minor-logo.png")
chromelogo=chromelogo.subsample(10,10)
treeview.pack(fill=BOTH,expand=True)
treeview.insert('','0','Chrome',text='Chrome', image=chromelogo)
treeview.insert('Chrome','0',"shit",text="shit",image=chromelogo)
treeview.insert('','1','Chrome3',text='Chrome3')
The link for chrome logo: http://logos-download.com/wp-content/uploads/2016/05/Chrome_icon_bright.png
Photoimage doesn't let you open images rather that a gif type if you want to open an image rather than gif in tkinter try the PIL module. you could use any method to install the PIL module, i like the command line
python -m pip install pillow
since you want to your image to feet in the tree view use this to resize and insert it
from tkinter import *
from tkinter import ttk
from PIL import ImageTk,Image
win=Tk()
chromelogo=Image.open("./Images/minor-logo.png")#open the image using PIL
imwidth=10#the new width you want
#the next three lines of codes are used to keep the aspect ration of the image
wpersent=(imwidth/float(chromelogo.size[0]))
hsize=int(float(chromelogo.size[1])*float(wpersent))#size[1] means the height and the size[0] means the width you can read more about this in th PIL documentation
chromelogo=ImageTk.PhotoImage(chromelogo.resize((imwidth,hsize),Image.ANTIALIAS))# set the width and put it back in the chromelogo variable
treeview=ttk.Treeview(win)
treeview.pack(fill=BOTH,expand=False)
treeview.insert('','0','Chrome',text='Chrome', image=chromelogo)
treeview.image = chromelogo#this one is for telling tkinter not to count the image as garbage
treeview.grid(row=0,rowspan=2,columnspan=2,padx=220,sticky=N+W,pady=20)
chromelogo2=ImageTk.PhotoImage(Image.open("./Images/minor-logo.png"))
treeview.insert('Chrome','0',"shit",text="shit",image=chromelogo2)#here you can also insert the unresized logo so you could see it as big as it is
treeview.insert('','1','Chrome3',text='Chrome3')
win.mainloop()
Simply converting "chromelogo" into a class variable by using the self keyword should fix the problem:
treeview=ttk.Treeview(frame3)
self.chromelogo=PhotoImage(file="./Images/minor-logo.png")
self.chromelogo=self.chromelogo.subsample(10,10)
treeview.pack(fill=BOTH,expand=True)
treeview.insert('','0','Chrome',text='Chrome', image=self.chromelogo)
treeview.insert('Chrome','0',"shit",text="shit",image=self.chromelogo)
treeview.insert('','1','Chrome3',text='Chrome3')

Access qrpython images without writing them to file

Here's my problem.
I'm building a simple QR-code generator with qrcode and PyQt4. In particular, this application shows an image of the generated QR-code inside a QPixmap of a QLabel. The problem is that the qrmodule, as far as I know, allows only to save the generated image to a file. I tried to access the inner workings of qrcode but it's kind of convoluted.
Do you know if it's possible to expose the image by saving the resulting image in a file stream, like the one from tempfile.TemporaryFile()? Otherwise I can only insert the qr-code by saving it on a real file and then loading it. For example
import qrcode as q
from PyQt4 import QtGui
filename = 'path/to/file.png'
img = q.make('Data')
img.save(filename)
pixmap = QtGui.QPixmap(filename)
EDIT 1
I tried to use the PIL.ImageQt.ImageQt function as proposed in an answer in the following way
import sys
import qrcode as qr
from PyQt4 import QtGui
from PIL import ImageQt
a = QtGui.QApplication(sys.argv)
l = QtGui.QLabel()
pix = QtGui.QPixmap.fromImage(ImageQt.ImageQt(qr.make("Some test data")))
l.setPixmap(pix)
l.show()
sys.exit(a.exec_())
The result is not however consistent. This is the result obtained using the method above
And this is the result using qrcode.make('Some test data').save('test2.png')
Am I missing something? The ImageQt function si a subclass of QImage as far as I understand, in fact I get no runtime errors, but the image is corrupted.
It turns out it takes a couple of steps to do this but you don't need to mess around with intermediate files. Note that the QRcode that qrcode generates is a PIL (python image library but its best to use the fork pillow) object. PIL provides the handy ImageQt module to convert your QR code into an Qimage object. Next you need to use the method QtGui.QPixmap.fromImage to create a pixmap (this method seg faults unless qt's initialisation has been done). The complete code would look something like this:
>>> import qrcode as q
>>> from PyQt4 import QtGui
>>> from PIL import ImageQt
>>> import sys
>>> app = QtGui.QApplication(sys.argv) # line 8 seg faults without this
>>> qrcode = q.make("some test data")
>>> qt_image = ImageQt.ImageQt(qrcode)
>>> pixmap = QtGui.QPixmap.fromImage(qt_image)
Obviously you can neaten that up somewhat but it works.

videocapture and pyqt

i use this lib http://videocapture.sourceforge.net/ for a capturing web cam. But i don't understand how it video-stream send to qpixmap.
If you check out the documentation for this library, you will see its very short and sweet. http://videocapture.sourceforge.net/html/VideoCapture.html
There are two ways I can tell you that you could get your image into Qt...
The best way - Directly into a QImage
getImage() states that it will return a PIL image. PIL, if you are using the latest version, has a module called ImageQt which can take a PIL Image object and give you back a QImage. From here you could convert that to QPixmap:
from PyQt4 import QtCore, QtGui
from VideoCapture import Device
from PIL import Image, ImageQt
app = QtGui.QApplication([])
cam = Device()
# this is a PIL image
pilImage = cam.getImage()
# this is a QImage
qImage = ImageQt.ImageQt(pilImage)
# this is a QPixmap
qPixmap = QtGui.QPixmap.fromImage(q)
The other way - Write to disk first
If you follow the example they give on this modules website, they show you how to use saveSnapshot() to save the image to disk. This is less desirable than the first method since you have to do disk i/o, but I will still mention it. You would then read it into your Qt app as a QPixmap:
cam = Device()
cam.saveSnapshot('image.jpg')
qPixmap = QtGui.QPixmap('image.jpg')
Do the first method. Its faster and more efficient.

Categories