how to embed an image in a text widget - python

I know it is possible to embed an image in a Tkinter text widget, but I've been unable to find some simple example code.
Specifically, I need to embed a jpg, so according to the docs I think I need to use the photoimage class
I tried to use this:
img=PhotoImage ( file=imgfn )
text.image_create(image=img)
where imgfn is the image filename, and text is my text widget,
but I get "_tkinter.TclError: couldn't recognize data in image file ..."
thanks for any help!

PhotoImage only handles GIF and PGM/PPM files. In order to use JPEG with Tkinter, you can use the Python Imaging Library (PIL) to create a PhotoImage.
from PIL import Image, ImageTk
img = Image.open("yourimg.jpg")
photoImg = ImageTk.PhotoImage(img)
Alternatively you could just one of the other supported formats for PhotoImage if possible.

Related

Tkinter Create Line with Stipple

I found the possibility to make a stippled line in Python tkinter. (Seen here: Canvas Line Objects)
It states that I need a bitmap file and define stipple=bitmap_file
I tried this in:
# Import the required libraries
from tkinter import *
# Create an instance of tkinter frame or window
win=Tk()
# Set the size of the tkinter window
win.geometry("700x350")
# Create a canvas widget
canvas=Canvas(win, width=500, height=300)
canvas.pack()
# Add a line in canvas widget
canvas.create_line(100,200,200,35, stipple='#CheckedLine.bmp', fill='red', width=5)
win.mainloop()
However, the console then says:
_tkinter.TclError: error reading bitmap file "CheckedLine.bmp"
Can someone help?
The page linked to in the OP, also links to a detailed description of what they meant by a "bitmap", they never mention it to be a file but rather a bitmap.
stipple
To draw a stippled line, set this option to a bitmap that specifies
the stippling pattern, such as stipple='gray25'. See Section 5.7,
“Bitmaps” for the possible values.
Section 5.7 details about the files to be used -:
The graphic above shows Button widgets bearing the standard bitmaps.
From left to right, they are 'error', 'gray75', 'gray50', 'gray25',
'gray12', 'hourglass', 'info', 'questhead', 'question', and 'warning'.
You can use your own bitmaps. Any file in .xbm (X bit map) format will
work. In place of a standard bitmap name, use the string '#' followed
by the pathname of the .xbm file.
For more information on the .xbm format this may be useful.
Some image viewers/converters, e.g., XnView, FFmpeg and IrfanView,
support XBM. A 48×48 XBM can be converted to Ikon and eventually
X-Face with Netpbm tools.
ImageMagick supports converting images both to and from XBM. GIMP
may be used to create or modify images using the XBM format, and also
supports converting images to and from the XBM format.
NOTE:
Incase, you use the standard bitmaps as listed above and in the link provided, they render to look like this -:

i get an error when trying to add an image to python tkinter

hi so have this image in the same directory as my .py file . and i changed the image from "background.jpg" to "background.gif" because i heard it helps
when i hover my cursor over the file=background.gif it show me the image so it can read it
but when i try to run . it give me an error and says "couldn't recognize data in image file "background.gif""
from tkinter import *
root = Tk()
photo = PhotoImage(file="background.gif")
label = Label(root, image=photo)
label.pack()
root.mainloop()
code
error
I think the problem here really is(as acw1668 mentioned) because you didn't use an image converter to convert the image, instead just simply renamed the file to .gif, which is not the correct way of changing file formats and can damage the file at times. Using an jpg to gif converter online can clear this issue and give you a gif that works :D

How to save image data from clipboard to a file in Python 3 on Debian, using tkinter?

I'm trying to use the tkinter solution for obtaining clipboard image data copied from GIMP, but cannot make it work, saving the data to file:
from tkinter import Tk
r = Tk()
r.withdraw()
clip = r.clipboard_get(type="image/png")
r.update()
r.destroy()
with open("testbytes.png", mode="bw+") as f:
f.write(clip.encode())
When I try to open the testbytes.png file, the Image Viewer reports a fatal error, not a PNG file. I obtained the type parameter for the clipboard_get() call with r.selection_get(selection='CLIPBOARD', type='TARGETS'), which returned:
'TIMESTAMP TARGETS MULTIPLE SAVE_TARGETS image/png image/bmp image/x-bmp image/x-MS-bmp image/x-icon image/x-ico image/x-win-bitmap image/vnd.microsoft.icon application/ico image/ico image/icon text/ico image/tiff image/jpeg '
I think the format of the data on the clipboard is PNG. I've also tried JPEG, BMP and TIFF, but they result in similar errors.
What am I doing wrong?
Using a conversion method, obtained in a separate SO question, for the hexdump of PNG data that tkinter provides from the clipboard, the correct code is:
from tkinter import Tk
r = Tk()
r.withdraw()
clip = r.clipboard_get(type="image/png")
r.update()
r.destroy()
# Convert hexdump to bytes
clip = bytes([eval(h) for h in clip.strip().split(' ')])
with open("testbytes.png", mode="bw+") as f:
f.write(clip)
Apart from writing out a PNG file, the data may also be loaded with the pillow module (formerly known as PIL):
import io
from PIL import Image
cf = io.BytesIO(clip)
cim = Image.open(cf)
cim.show()
As far as I've been able to determine, this is the best method of reading a PNG file from the clipboard into Python 3 on Linux (Debian).
I have created a tool for this intended for windows. The code could be used for debian as well. This script monitors for change in your clipboard and pops up a tkinter window asking you the filename to be used for saving the image, if it is not present in the folder. The image is then saved into the folder as a PNG file. It is particularly helpful with the windows shortcut Windows + Shift + S used to snip the screen.
Please find it here: https://github.com/Mitzzzzz/Clipboard-Image-Saver

python imaging library save function

I have just done some image processing using the python image library (PIL) and I can't get the save function to work. the whole code works fine but it just wont save the resulting image. The code is below:
im=Image.new("rgb",(200,10),"#ddd")
draw=Image.draw.draw(im)
draw.text((10,10),"run away",fill="red")
im.save("g.jpeg")
Saving gives an error as unknown extension and even removing the dot doesn't help.
Use .jpg:
im.save("g.jpg")
The image library determines what encoder to use by the extension, but in certain versions of PIL the JPEG encoder do not register the .jpeg extension, only .jpg.
Another possibility is that your PIL installation doesn't support JPEG at all; try saving the image as a PNG, for example.
Replace
draw=Image.draw.draw(im)
with
draw = ImageDraw.Draw(im)
and make sure the height of the new image is tall enough to accomodate the text.
import Image
import ImageDraw
im = Image.new("RGB", (200, 30), "#ddd")
draw = ImageDraw.Draw(im)
draw.text((10, 10), "run away", fill="red")
im.save("g.jpeg")
yields
please save with .jpg extention eg:
im.save("g.jpg")

Python images display

How can I create a python script that runs through the images (1.jpeg-n.jpeg) in a directory on a mac and displays them in a browser OR via another python program?
Do I import a file to python and than display in browser?
Do I extract the file names 1,2,3,4,5 and add that to a list, which I give to another function that calls a browser and displays?
Any help would be great.
Thanks!
Using Tkinter and PIL for this purpose is pretty trivial. Add muskies example to the information from this thread that contains this example:
# use a Tkinter label as a panel/frame with a background image
# note that Tkinter only reads gif and ppm images
# use the Python Image Library (PIL) for other image formats
# free from [url]http://www.pythonware.com/products/pil/index.htm[/url]
# give Tkinter a namespace to avoid conflicts with PIL
# (they both have a class named Image)
import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
root.title('background image')
# pick an image file you have .bmp .jpg .gif. .png
# load the file and covert it to a Tkinter image object
imageFile = "Flowers.jpg"
image1 = ImageTk.PhotoImage(Image.open(imageFile))
# get the image size
w = image1.width()
h = image1.height()
# position coordinates of root 'upper left corner'
x = 0
y = 0
# make the root window the size of the image
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
# root has no image argument, so use a label as a panel
panel1 = tk.Label(root, image=image1)
panel1.pack(side='top', fill='both', expand='yes')
# put a button on the image panel to test it
button2 = tk.Button(panel1, text='button2')
button2.pack(side='top')
# save the panel's image from 'garbage collection'
panel1.image = image1
# start the event loop
root.mainloop()
Of course if you're more familiar with another GUI, go ahead and adapt the example, it shouldn't take much.
You first have to find all image filenames. You can use os.listdir(...) to get all files in a certain directory, or glob.glob(...) to find all files matching a certain pattern.
Showing the images is the second and more challenging part of this. The first option is to open the images in an external program, this can be a web browser. On (most) platforms a command firefox 1.jpeg will open the image 1.jpeg in the Firefox browser. You can use the subprocess module to execute such commands. If you want to show them using a nice GUI, you have to create a GUI using some framework and use this. But if you are a beginner this might be a little bit too difficult for you.
For example:
import glob
import subprocess
files = glob.glob('dir/*.jpeg')
for file in files:
subprocess.call(['firefox', file])
muksie's answer already contains very useful advice. If don't want to write the HTML file yourself or want something a little fancier you could use a small script I wrote for the MDP library. This basically allows you to just do:
import slideshow
slideshow.show_image_slideshow(filenames, image_size=(80,60))
This will create an HTML slideshow and open it in your browser. You can grab just the needed files here (only templet.py and the two slideshow files are needed), which might be better for you than getting the full library.
It might be a lot easier to just generate a static web page with pictures than building a GUI for displaying pictures.
You can just generate a hmtl page, put the images on it and start your web browser with the newly created html file. this gives you some possibilities for layout as well.
If you just want a picture in the browser then muksie gave a working example.

Categories

Resources