Pillow & Tkinter doesn't show PNGs with transparency - python-3.x

My application was recently working fine, but when I upgraded Python to v3.7.2, which solved another problem I was having, the images are either no longer shown or of poor quality.
After doing some testing, I've concluded that I can display any PNG without transparency, but PNGs with transparency exhibit this problem. I can recreate it with this code:
import tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
path = 'png-transparent.png'
img = Image.open(path)
imgtk = ImageTk.PhotoImage(img)
panel = tk.Label(root, image=imgtk).pack()
root.mainloop()
If I use a label to display the image, it doesn't show at all. If I use a button to display the image, which is what I really need to do, it is poor quality (which means not displaying properly, no definition, coarse edges).
They are very small (16x16), but you can see two different icons here, the ones in the boxes are the distorted ones and the ones not in boxes are how they are supposed to look.
Current versions: Python 3.7.2, Pillow 5.4.1, OS X 10.13.6

Related

Why is a generated SVG image less rich than the corresponding PNG image

To set this up, I used svgwrite library to create a sample SVG image (20 squares of length 100 at random locations on a display size of length 400)
import svgwrite
import random
random.seed(42)
dwg = svgwrite.Drawing('x.svg', size=(400,400))
dwg.add(dwg.rect(insert=(0,0), size=('100%', '100%'), fill='white')) # White background
for i in range(20):
coordinates = (random.randint(0,399), random.randint(0,399))
color = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
dwg.add(dwg.rect(coordinates, (100, 100),
stroke='black',
fill=svgwrite.rgb(*color),
stroke_width=1)
)
dwg.save()
I then wrote a sample pygame program to generate a PNG image of the same sample. (A seed has been used to generate the same sequence of squares.)
import pygame
import random
random.seed(42)
display = pygame.display.set_mode((400,400))
display.fill((255,255,255)) # White background
for i in range(20):
coordinates = (random.randint(0,399), random.randint(0,399))
color = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
pygame.draw.rect(display, color, coordinates+(100,100), 0)
pygame.draw.rect(display, (0,0,0), coordinates+(100,100), 1) #For black border
pygame.image.save(display, "x.png")
These are the images that I got (SVG's can't be uploaded to SO, so I have provided a screenshot. Nevertheless, the programs above can be run to output the same).
My question is, why is the PNG (on the left) richer and sharper than the corresponding SVG image? The SVG looks blurred and bland, comparatively.
EDIT: One can notice the fine white line between the first two squares at the top-left corner. It's not very clear in the SVG.
Two things I think may impact:
You are using an image viewer, which could distort the vectorial SVG image. I think all of the vector images viewers get the actual screen size, then export the vectorial image into a matrix image sized in function of the size of the screen you have. Then they display the matrix image. If they render the image with softened sharpness, or if they have a problem by getting the size of your screen, the image may be blurred.
To make the PNG image, you use pygame. But you are using another module to make the SVG image. This module may function differently, and also exports the image with another quality than if you were exporting it with pygame.
For me personally the SVG image appears blurred with Gimp, for example, but not with another SVG viewer.
So I think the problem comes from your image viewer.

Tkinter fullscreen leaves border

I am trying to make an image slide show application using Tkinter and Pillow. I would like the image to go full screen, so currently my code looks like this (I think these are all the important bits, ask me if you need to see more):
canvas = Canvas(root, width=screenwidth, height=screenheight, bg=‘black’)#screenwidth and height previously assigned (checked to be correct) variables containing screen dimensions.
image = image.resize((resizew, resizeh) Image.ANTIALIAS)
imagesprite = canvas.create_image(midx, midy, image=photo) #had changed our resized image to a tkinter photo image previously, midx and midy are just half the screen dimensions.
The problem:
No matter what settings I change there is always some form of grey bar around the edge of the window. I have tried changing the window size, changing the canvas size, setting the window geometry manually using root.geometry to no avail. However, some of the combinations of settings lead to there being fewer bars; I have seen between 1 and 3. Pictures of the output in its current state are attached. There are no errors in the shell, not (currently) is there a border on the left of the image
[1]: https://i.stack.imgur.com/1DLfg.jpg
You need to set highlightthickness=0 when creating the canvas:
canvas = Canvas(root, width=screenwidth, height=screenheight, bg='black', highlightthickness=0)

Why does putting image on a black background cause a problem in numpy?

import cv2
import numpy as np
def mycvshow(imagein, title='Image'): #title can be specified or left to the default
cv2.imshow(title,imagein)
cv2.waitKey()
#cv2.destroyWindow(title)
img_gray=cv2.imread('cat.jpg',0)
big_picture=np.zeros((img_gray.shape[0]+1000,img_gray.shape[1]+1000))
big_picture[0:img_gray.shape[0],0:img_gray.shape[1]]=img_gray
mycvshow(big_picture)
The above is my code. I read in an image in grayscale and then put it in a large matrix of zeros. I expect it to return a picture of a cat with a black background but it just breaks the mycvshow function and shows an almost completely white picture of the cat on a black background and window displaying the image seems to have problems too. Everything goes perfectly if i just write mycvshow(img_gray).

Text format chooser in Tkinter possible? [duplicate]

I'm trying to write simple notepad with Tkinter. And I need some font chooser. So my question is: is there included one? and if there isn't, where can I get one?
Thanks.
Tk (and Tkinter) doesn't have any font chooser in the default distribution. You'll need to create your own. Here is an example I found: Tkinter FontChooser
Note: Tk 8.6 will have a build in font chooser dialog: FontChooser
The basis for a simple font selector can be found below
import tkinter as tk
from tkinter import font
def changeFont(event):
selection = lbFonts.curselection()
laExample.config(font=(available_fonts[selection[0]],"16"))
root = tk.Tk()
available_fonts = font.families()
lbFonts = tk.Listbox(root)
lbFonts.grid()
for font in available_fonts:
lbFonts.insert(tk.END, font)
lbFonts.bind("<Double-Button-1>", changeFont)
laExample = tk.Label(root,text="Click Font")
laExample.grid()
root.mainloop()
Double clicking on a font in the list will change the example text below to that font. You can scroll down through the list of fonts by using a mouse wheel (or you can add a scroll bar to it)
There is a font chooser window in tkinter but it has been discontinued in the newer versions but you can still access it.
l = ttk.Label(root, text="Hello World", font="helvetica 24")
l.grid(padx=10, pady=10)
def font_changed(font):
l['font'] = font
root.tk.call('tk', 'fontchooser', 'configure', '-font', 'helvetica 24', '-command', root.register(font_changed))
root.tk.call('tk', 'fontchooser', 'show')
Check this link for more details: https://tkdocs.com/tutorial/windows.html
Use rvfont module for font chooser It is easy to use
pip install rvfont
code:
from rvfont.rvfontchooser import FontDialog
fonts=FontDialog()
It will give fonts option in dictionary

Background color of tkinter label will not change (python 3.4)

I am making a widget with Tkinter in python 3.4. For some reason, I cannot change a label's background color from the default grey. The code for the label is something like this:
self.label = ttk.Label(master, text="Label Text",
foreground="blue", background="yellow")
Everything else works fine. I can change the foreground (text) color, however the background will not change, whether I am using label.config(), label['background'], or whatever.
I can change the background if I write it for Python 2.7, but I am using tutorials for Tkinter in 3.4, so this is undesirable.
This bug is caused by the 'aqua' ttk style on Mac OSX. It also breaks 'ttk.Progressbar' when set to 'indeterminate' mode. To fix both issues insert the following code after 'root = Tk()' to change the style ...
style = ttk.Style()
style.theme_use('classic') # Any style other than aqua.
This solution was posted by dietrich41
here : http://www.python-forum.org/viewtopic.php?f=12&t=16212
I tested it on a Mac running Python 3.4.1.

Resources