How to show PIL images on the screen? - python

I am doing some image editing with the PIL libary. The point is, that I don't want to save the image each time on my HDD to view it in Explorer. Is there a small module that simply enables me to set up a window and display the image?

From near the beginning of the PIL Tutorial:
Once you have an instance of the Image class, you can use the methods
defined by this class to process and manipulate the image. For
example, let's display the image we just loaded:
     >>> im.show()
Update:
Nowadays the Image.show() method is formally documented in the Pillow fork of PIL along with an explanation of how it's implemented on different OSs.

I tested this and it works fine for me:
from PIL import Image
im = Image.open('image.jpg')
im.show()

You can use pyplot to show images:
from PIL import Image
import matplotlib.pyplot as plt
im = Image.open('image.jpg')
plt.imshow(im)
plt.show() # image will not be displayed without this

If you find that PIL has problems on some platforms, using a native image viewer may help.
img.save("tmp.png") #Save the image to a PNG file called tmp.png.
For MacOS:
import os
os.system("open tmp.png") #Will open in Preview.
For most GNU/Linux systems with X.Org and a desktop environment:
import os
os.system("xdg-open tmp.png")
For Windows:
import os
os.system("powershell -c tmp.png")

Maybe you can use matplotlib for this, you can also plot normal images with it. If you call show() the image pops up in a window. Take a look at this:
http://matplotlib.org/users/image_tutorial.html

You can display an image in your own window using Tkinter, w/o depending on image viewers installed in your system:
import Tkinter as tk
from PIL import Image, ImageTk # Place this at the end (to avoid any conflicts/errors)
window = tk.Tk()
#window.geometry("500x500") # (optional)
imagefile = {path_to_your_image_file}
img = ImageTk.PhotoImage(Image.open(imagefile))
lbl = tk.Label(window, image = img).pack()
window.mainloop()
For Python 3, replace import Tkinter as tk with import tkinter as tk.

Yes, PIL.Image.Image.show() easy and convenient.
But if you want to put the image together, and do some comparing, then I will suggest you use the matplotlib. Below is an example,
import PIL
import PIL.IcoImagePlugin
import PIL.Image
import matplotlib.pyplot as plt
with PIL.Image.open("favicon.ico") as pil_img:
pil_img: PIL.IcoImagePlugin.IcoImageFile # You can omit. It helps IDE know what the object is, and then it will hint at the method very correctly.
out_img = pil_img.resize((48, 48), PIL.Image.ANTIALIAS)
plt.figure(figsize=(2, 1)) # 2 row and 1 column.
plt.subplots_adjust(hspace=1) # or you can try: plt.tight_layout()
plt.rc(('xtick', 'ytick'), color=(1, 1, 1, 0)) # set xtick, ytick to transparent
plt.subplot(2, 1, 1), plt.imshow(pil_img)
plt.subplot(2, 1, 2), plt.imshow(out_img)
plt.show()

This is what worked for me:
roses = list(data_dir.glob('roses/*'))
abc = PIL.Image.open(str(roses[0]))
PIL.Image._show(abc)

Related

Photoimage is not working in tkinter. Gives an error now but from start

from tkinter import *
from tkinter import ttk
win = Tk()
colorful=PhotoImage(file='image/1.png')
_tkinter.TclError: couldn't recognize data in image file "image/1.png" file path is correct, from beginning it was running without an error but when I add some more code it happened, why?
Try this:
from PIL import Image, ImageTk
img = Image.open("file_name")
colorful = ImageTk.PhotoImage(img)
Tkinter Photoimage only supports .gif images.
If you want to display .png images, Use PIL (Python Imaging Library)
Fore more info, see https://pythonbasics.org/tkinter-image/ .

take full screenshot python

I am trying to take a screenshot for my screen(s).
I am aware of the function
pyautogui.screenshot()
The problem with this function is that it can take a screenshot for one screen only. I am trying to take a full screenshot for all available screens (typically two). But, it does not seem to work in this regards.
Given the fact that you want to use a Windows system I would like to suggest you to use Desktopmagic, a Python Library.
Here's an example:
from __future__ import print_function
from desktopmagic.screengrab_win32 import (
getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage,
getRectAsImage, getDisplaysAsImages)
# Save the entire virtual screen as a BMP (no PIL required)
saveScreenToBmp('screencapture_entire.bmp')
# Save an arbitrary rectangle of the virtual screen as a BMP (no PIL required)
saveRectToBmp('screencapture_256_256.bmp', rect=(0, 0, 256, 256))
# Save the entire virtual screen as a PNG
entireScreen = getScreenAsImage()
entireScreen.save('screencapture_entire.png', format='png')
# Get bounding rectangles for all displays, in display order
print("Display rects are:", getDisplayRects())
# -> something like [(0, 0, 1280, 1024), (-1280, 0, 0, 1024), (1280, -176, 3200, 1024)]
# Capture an arbitrary rectangle of the virtual screen: (left, top, right, bottom)
rect256 = getRectAsImage((0, 0, 256, 256))
rect256.save('screencapture_256_256.png', format='png')
# Unsynchronized capture, one display at a time.
# If you need all displays, use getDisplaysAsImages() instead.
for displayNumber, rect in enumerate(getDisplayRects(), 1):
imDisplay = getRectAsImage(rect)
imDisplay.save('screencapture_unsync_display_%d.png' % (displayNumber,), format='png')
# Synchronized capture, entire virtual screen at once, cropped to one Image per display.
for displayNumber, im in enumerate(getDisplaysAsImages(), 1):
im.save('screencapture_sync_display_%d.png' % (displayNumber,), format='png')
I would suggest another module if you mind: MSS (you do not need PIL or any other module, just Python; and it is cross-platform):
from mss import mss
with mss() as sct:
sct.shot(mon=-1, output="fullscreen.png")
The documentation tries to explain more things, if you are interested.
Using pyscreenshot library worked for me, I took a screenshot of all screens.
Source: https://pypi.org/project/pyscreenshot/
#-- include('examples/showgrabfullscreen.py') --#
import pyscreenshot as ImageGrab
if __name__ == '__main__':
# grab fullscreen
im = ImageGrab.grab()
# save image file
im.save('screenshot.png')
# show image in a window
im.show()
#-#
If you don't want to open the GUI, just comment the im.show() line.

How to properly scale/rotate images in pyqtgraph?

I have implemented pyqtgraph inside QGraphicsView in PyQt5. When I display the image the following way, it is stretched out and expands in the same aspect ratio as the screen. How do I fix this?
image = pg.ImageItem(asarray(Image.open('pic.png')) )
self.graphicsView.addItem(image)
image.rotate(270)
EDIT: found out how to rotate image, so I updated question with the solution. Now I am just trying to scale it properly.
You probably want something like:
import pyqtgraph as pg
from PIL import Image
from numpy import asarray
app = pg.mkQApp()
# Set up a window with ViewBox inside
gv = pg.GraphicsView()
vb = pg.ViewBox()
gv.setCentralItem(vb)
gv.show()
# configure view for images
vb.setAspectLocked()
vb.invertY()
# display image
img_data = asarray(Image.open('/home/luke/tmp/graph.png'))
image = pg.ImageItem(img_data, axisOrder='row-major')
vb.addItem(image)
The important pieces here that set the image scaling/orientation are:
using ImageItem(axisOrder='row-major') because image files are stored in row-major order
vb.invertY() because image files have the +y axis pointing downward
and vb.setAspectLocked() to keep the pixels square
I used np.rot90() instead, it's much faster and cythonable
image = pg.ImageItem(np.rot90(np.asarray(Image.open('pic.png'))))

How can I display an image using Pillow?

I want to display a gif image using Pillow
Here is my simple code:
from tkinter import *
from PIL import Image, ImageTk
import tkinter as Tk
image = Image.open("Puissance4.gif")
image.show()
But nothing happens...
All help will be appreciated
Thanks!
PIL provides a show method which attempts to detect your OS and choose an
appropriate viewer. On Unix it tries calling the imagemagick command display
or xv. On Macs it uses open, on Windows it uses... something else.
If it can't find an appropriate viewer, ImageShow._viewers will be an empty list.
On Raspbian, you'll need to install an image viewer such as display, xv or fim. (Note a search on the web will show that there are many image viewers available.) Then
you can tell PIL to use it by specifying the command parameter:
image.show(command='fim')
To display an image in Tkinter, you could use something like:
from PIL import Image, ImageTk
import tkinter as tk
root = tk.Tk()
img = Image.open("image.gif")
tkimage = ImageTk.PhotoImage(img)
tk.Label(root, image=tkimage).pack()
root.mainloop()

Taking Screen shots of specific size

What imaging modules for python will allow you to take a specific size screenshot (not whole screen)?
I have tried PIL, but can't seem to make ImageGrab.grab() select a small rectangle
and i have tried PyGame but i can't make it take a screen shot outside of it's main display panel
You can use pyscreenshot module.
The pyscreenshot module can be used to copy the contents of the screen to a PIL image memory or file.
You can install it using pip.
$ sudo pip install pyscreenshot
Usage:
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')
I have tried PIL, but can't seem to make ImageGrab.grab() select a small rectangle
What did you try?
As the documentation for ImageGrab clearly states, the function has a bbox parameter, and:
The pixels inside the bounding box are returned as an “RGB” image. If the bounding box is omitted, the entire screen is copied.
So, you only get the whole screen if you don't pass a bbox.
Note that, although I linked to the Pillow docs (and you should be using Pillow), old-school PIL's docs say the same thing:
The bounding box argument can be used to copy only a part of the screen.
So, unless you're using a really, really old version of PIL (before 1.1.3, which I believe is more than a decade out of date), it has this feature.
1) Use pyscreenshot, ImageGrab works but only on Windows
2) Grab the image and box it, then save that image
3) Don't use ImageGrab.grab_to_file, it saves the full size image
4) You don't need to show the image with im.show if you just want to save a screenshot
import pyscreenshot as ImageGrab
im=ImageGrab.grab(bbox=(10,10,500,500))
im.save('im.png')
You could use Python MSS.
From documentation to capture only a part of the screen:
import mss
import mss.tools
with mss.mss() as sct:
# The screen part to capture
monitor = {"top": 160, "left": 160, "width": 160, "height": 135}
output = "sct-{top}x{left}_{width}x{height}.png".format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
mss.tools.to_png(sct_img.rgb, sct_img.size, output=output)
print(output)
You can use pyscreenshot at linux or windows platforms . I am using Ubuntu it works for me. You can force if subprocess is applied setting it to false together with mss gives the best performance.
import pyscreenshot as ImageGrab
import time
t1 = time.time()
imgScreen = ImageGrab.grab(backend="mss", childprocess=False)
img = imgScreen.resize((640,480))
img.save("screen.png")
t2 = time.time()
print("The passing time",(t2-t1))

Categories

Resources