How to set the image size to display? Running in VSCode Jupyter Interactive Window
from PIL import Image
from IPython.display import display
display(Image.open('imageURL'))
This code displays the Image as it is, i.e showing the original size,
Tried this, which works, but how to keep the ratio, image shrunks as it is
image = Image.open('imageURL')
image = image.resize((500,500),Image.ANTIALIAS)
display(image)
Try
from IPython.display import Image, display
display(Image('image.png', width=600))
You can also set a height.
Try this code
image = Image.open("imageURL")
scale = 0.3
display(image.resize(( int(image.width * scale), int(image.height * scale))))
If you are dealing with video, you can do the following:
from IPython.display import display, Video
display(Video(data=video_path, embed=True, width = 600, height = 300))
Note: It is not an answer to the image, but it is described as a reference.
Related
Probably an unusual question, but I am currently looking for a solution to display image files with PIL slower.
Ideally so that you can see how the image builds up, pixel by pixel from left to right.
Does anyone have an idea how to implement something like this?
It is a purely optical thing, so it is not essential.
Here an example:
from PIL import Image
im = Image.open("sample-image.png")
im.show()
Is there a way to "slow down" im.show()?
AFAIK, you cannot do this directly with PIL's Image.show() because it actually saves your image as a file to /var/tmp/XXX and then passes that file to your OS's standard image viewer to display on the screen and there is no further interaction with the viewer process after that. So, if you draw in another pixel, the viewer will not be aware and if you call Image.show() again, it will save a new copy of your image and invoke another viewer which will give you a second window rather than updating the first!
There are several possibilities to get around it:
use OpenCV's cv2.imshow() which does allow updates
use tkinter to display the changing image
create an animated GIF and start a new process to display that
I chose the first, using OpenCV, as the path of least resistance:
#!/usr/bin/env python3
import cv2
import numpy as np
from PIL import Image
# Open image
im = Image.open('paddington.png')
# Make BGR Numpy version for OpenCV
BGR = np.array(im)[:,:,::-1]
h, w = BGR.shape[:2]
# Make empty image to fill in slowly and display
d = np.zeros_like(BGR)
# Use "x" to avoid drawing and waiting for every single pixel
x=0
for y in range(h):
for x in range(w):
d[y,x] = BGR[y,x]
if x%400==0:
cv2.imshow("SlowLoader",d)
cv2.waitKey(1)
x += 1
# Wait for one final keypress to exit
cv2.waitKey(0)
Increase the 400 near the end to make it faster and update the screen after a greater number of pixels, or decrease it to make it update the screen after a smaller number of pixels meaning you will see them appear more slowly.
As I cannot share a movie on StackOverflow, I made an animated GIF to show how that looks:
I decided to try and do it with tkinter as well. I am no expert on tkinter but the following works just the same as the code above. If anyone knows tkinter better, please feel free to point out my inadequacies - I am happy to learn! Thank you.
#!/usr/bin/env python3
import numpy as np
from tkinter import *
from PIL import Image, ImageTk
# Create Tkinter Window and Label
root = Tk()
video = Label(root)
video.pack()
# Open image
im = Image.open('paddington.png')
# Make Numpy version for simpler pixel access
RGB = np.array(im)
h, w = RGB.shape[:2]
# Make empty image to fill in slowly and display
d = np.zeros_like(RGB)
# Use "x" to avoid drawing and waiting for every single pixel
x=0
for y in range(h):
for x in range(w):
d[y,x] = RGB[y,x]
if x%400==0:
# Convert the video for Tkinter
img = Image.fromarray(d)
imgtk = ImageTk.PhotoImage(image=img)
# Set the image on the label
video.config(image=imgtk)
# Update the window
root.update()
x += 1
I'm trying to display animations in Google Colab. Specifically, I would like to animate a numpy array with cv2, eg drawing lines in a frame-based manner, and show the output in the cell. The closest I got was this, you can try this code in Colab:
from google.colab.patches import cv2_imshow
import IPython
from PIL import Image
import numpy as np
import cv2 as cv
import time
# Create a black image
img = np.zeros((512,512,3), np.uint8)
# Draw a diagonal blue line with thickness of 5 px
cv.line(img,(0,0),(511,511),(255,0,0),5)
cv2_imshow(img)
for i in range(100):
cv.line(img,(i,0),(511,511),(255,0,0),5)
cv2_imshow(img)
IPython.display.clear_output(wait=True)
time.sleep(1/60.0)
At some point of course this should happen without time.sleep, but with repeated callbacks so we don't block any other code execution. However, as you can see, the output flickers and is not smooth at all.
Here are a couple things I've tried:
ipycanvas. This is great in a local Jupyter notebook and is based on HTML5 canvas. It is a bit annoying to get the image data from javascript back to python, but it's possible. However, this does not run in Google Colab.
https://ipycanvas.readthedocs.io/
Matplotlib animations. eg this (not mine):
https://colab.research.google.com/drive/1lnl5UPFWVPrryaZZgEzd0theI6S94c3X#scrollTo=QLRBwgFqdr83
This is alright. However, it renders the whole animation before displaying it, which is not what I want. Especially, I want to be able to add some interactivity to animations, which this limitation rules out (eg clicking in the image or some button to make something happen in the animation).
Some way of explicitly creating an HTML5 canvas in javascript, eg as suggested here:
IPython: Adding Javascript scripts to IPython notebook
However, I'd like all my code to be python, especially my data to be numpy arrays or PIL images.
Any suggestions?
Here's an example using ipywidgets.Image. This approach doesn't flicker like using clear_output, but the updates seem pretty slow. This might be to do with the fact we're running remotely from Colab - it has to send image updates over the net. Looks like I'm getting 2 or 3 per second, and it seems like it "batches up" or discards intervening updates, rather than waiting for each one.
It's pretty smooth running locally on regular Jupyter.
Hope someone can improve on this - it's something we want to do as well :)
import ipywidgets as ipw
from IPython import display
import numpy as np
import PIL
from io import BytesIO
import time
# image size
h,w = 200,300
# Make an Image Widget and display it
wIm = ipw.Image()
display.display(wIm)
# Make an RGBA array for the image
g3 = np.zeros((h,w,4), dtype=np.uint8)
g3[:,:,3] = 255 # opacity
g3[:,:,0:3] = 0 # color black
p = np.array([h//2,w//2], dtype=int)
for i in range(1000):
# Draw a coloured spiral
r = i/10
theta=i/20
p2 = p + r * np.array([ np.cos(theta), np.sin(theta) ])
(y,x) = p2.astype(int)
rgb = np.array([100+r, 100*(1+np.sin(theta)), 100*(1+np.cos(theta))], dtype=np.uint8)
g3[y:y+8, x:x+2, 0:3] = rgb
# convert numpy to PIL to png-format bytes
pilIm = PIL.Image.fromarray(g3, mode="RGBA")
with BytesIO() as fOut:
pilIm.save(fOut, format="png")
byPng = fOut.getvalue()
# set the png bytes as the image value;
# this updates the image in the browser.
wIm.value=byPng
time.sleep(1/60)
I have a very high resolution(3311, 4681, 3) image, which I want to show in my jupyter notebook using opencv but as other answers stated its not possible to use cv2.imshow in the jupyter notebook, so i used plt.imshow to do the same but the problem is I have to define the fig_size parameter if I want to display my image larger. How can I read the image in its original resolution in jupyter notebook or is it possible to open the image in another window?
This is what I have tried :
import cv2
from matplotlib import pyplot as plt
%matplotlib inline
img = cv2.imread(r"0261b27431-07_D_01.jpg")
plt.figure(figsize= (20,20))
plt.imshow(img)
plt.show()
So basically I want my image to show in its original resolution in jupyter notebook or in another window.
You can imshow the image in its original resolution by calculating the corresponding figure size, which depends on the dpi (dots per inch) value of matplotlib. The default value is 100 dpi and is stored in matplotlib.rcParams['figure.dpi'].
So imshowing the image like this
import cv2
from matplotlib import pyplot as plt
import matplotlib
%matplotlib inline
# Acquire default dots per inch value of matplotlib
dpi = matplotlib.rcParams['figure.dpi']
img = cv2.imread(r'0261b27431-07_D_01.jpg')
# Determine the figures size in inches to fit your image
height, width, depth = img.shape
figsize = width / float(dpi), height / float(dpi)
plt.figure(figsize=figsize)
plt.imshow(img)
plt.show()
prints it in its large resolution, but with the drawback, that the axis labels are tiny compared to the large image. You can workaround this by setting other rcParams to larger values, e.g.
# Do the same also for the 'y' axis
matplotlib.rcParams['xtick.labelsize'] = 50
matplotlib.rcParams['xtick.major.size'] = 15
matplotlib.rcParams['xtick.major.width'] = 5
...
Your second suggestion to open the image in another window would work like this, that you change the matplotlib backend using Ipython magic commands by replacing %matplotlib inline in the above example with, e.g.
%matplotlib qt # opens the image in an interactive window with original resolution
or
%matplotlib notebook # opens the image in an interactive window 'inline'
See here for more backend possibilites. Note that the calculation of the original figure size has to be done before also.
In order to show image in full original resolution,
You can also use PIL
from PIL import Image
img = Image.open(r'0261b27431-07_D_01.jpg')
img
I'm seeing a tiny difference in image I created using PIL of python than the actual one and because of this difference my sikuli script fails to click since its an image based automation tool.
The approach is to create an image & click it, based on the object name to be clicked on screen during run-time.
Code to create image :
import PIL
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
from PIL import ImageEnhance
font = ImageFont.truetype("C:\\SikuliWS\\R419\\Fonts\\calibri.ttf",11)
img=Image.new("RGBA", (0,0)) #To create an empty white background
draw = ImageDraw.Draw(img) #draw an image with 0,0
textsze = draw.textsize(imageString) #Create a text to capture w/h
print textsze
img=Image.new("RGBA", (textsze[0],textsze[1]+3),(255,255,255)) #create a white background as per the w/h of text passed
draw = ImageDraw.Draw(img)
draw.text((0, 0),imageString,(13,13,13),font=font)
img.save("imageString.png", format='PNG',quality=100)
Output:
Actual image created:
Expected image:
Notice the tiny difference between characters ID and the space between characters because of which sikuli fails to click.
How do I create an exact match of image using python 2.7? Please help.
I'm working with the python graphics module. What I am trying to do is save the current window as an image. In the module there is an option to save an "image" as an image (image.save()). But that isn't helpful because it just saves an image you have already loaded. OR if you load a blank image like I did in hopes drawing over it would change that, surprise, surprise: you get a blank image saved. Here is my code:
from graphics import *
w = 300
h = 300
anchorpoint=Point(150,150)
height=300
width=300
image=Image(anchorpoint, height, width) #creates a blank image in the background
win = GraphWin("Red Circle", w, h)
# circle needs center x, y coordinates and radius
center = Point(150, 150)
radius = 80
circle = Circle(center, radius)
circle.setFill('red')
circle.setWidth(2)
circle.draw(win)
point= circle.getCenter()
print point
pointx= point.getX()
pointy= point.getY()
print pointx
print pointy
findPixel=image.getPixel(150,150)
print findPixel
image.save("blank.gif")
# wait, click mouse to go on/exit
win.getMouse()
win.close()
#######that's it#####
so again here is my problem: How do I save what is now on the screen as "blank.gif"
Thanks!
The objects you are drawing are based on Tkinter. I don't believe you are actually drawing on the base image, but rather simply creating Tkinter objects by using the "graphics" library. I also don't believe you can save a Tkinter to a "gif" file, though you can definitely save them in postscript format, then covert them to a gif format.
In order to do this, you will need python's PIL library.
If all of your objects are actually TKinter objeccts, you can simply save the objects.
Start by replacing this line of code:
image.save("blank.gif")
With the following:
# saves the current TKinter object in postscript format
win.postscript(file="image.eps", colormode='color')
# Convert from eps format to gif format using PIL
from PIL import Image as NewImage
img = NewImage.open("image.eps")
img.save("blank.gif", "gif")
If you need additional information, please check out http://www.daniweb.com/software-development/python/code/216929 - which is where I got the suggested code.
I'm sure there are more elegant solutions available than save/convert, but since I don't know a lot about TKinter - this is the only way I've found.
Hope it helps!