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.
Related
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
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())
I need to add an image to the canvas. I have tried countless amounts of things, and finally decided to make a question on here.
This is what I have imported
from Tkinter import *
import tkFont
from PIL import ImageTk, Image
And this is the line of code I'm trying to add to import an image from the same folder the main file is in.
c.create_image(100,100, anchor=N, image = ghost.jpg)
I've also tried putting ""s around 'ghost.jpg' and it says the Image does not exist then. Without the quotes it says "global name 'ghost' does not exist."
Can anyone help?
Canvas.create_image's image argument
should be a PhotoImage or BitmapImage, or a
compatible object (such as the PIL's PhotoImage). The application must
keep a reference to the image object.
from Tkinter import *
"""python 2.7 =Tkinter"""
from PIL import Image, ImageTk
app = Tk()
temp=Image.open("photo.jpg")
temp = temp.save("photo.ppm","ppm")
photo = PhotoImage(file = "photo.ppm")
imagepanel=Label(app,image = photo)
imagepanel.grid()
app.mainloop()
This is a bit of code I wrote in python 2.7 with Tkinter and PIL to import a jpg file from a given directory, this doesn't pop up off the screen.
You should replace photo with the file name (and directory) and app with the relevant variable you set.
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.
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.