Extra pixels at top and bottom of label with image in tkinter - image

In Python 3.2.5 and tkinter, I keep getting 1 or 2 "extra" border-like pixels at the top and bottom of a middle label (of three stacked labels) containing an image (the sides do not have a white border). No matter how I shrink the window or designate no borderwidth, I get a couple of pixels beyond the top and bottom of the label(s).
Here's the code....
root.withdraw()
LoginErrorMsg = tk.Toplevel()
LoginErrorMsg.title('ERROR! Unauthorized Login Attempt')
# pick .gif file
# load the file and covert it to a tkinter image object
imageFile = "ErrorLogin.gif"
image1 = tk.PhotoImage(file=imageFile)
#set size of Error Message Window
width = 348
height = 480
#get size of the whole screen
xmax = LoginErrorMsg.winfo_screenwidth()
ymax = LoginErrorMsg.winfo_screenheight()
#calculate centered window coordinates and position it
x0 = xmax/2 - width/2
y0 = ymax/2 - height/2
LoginErrorMsg.geometry("%dx%d+%d+%d" % (width, height, x0, y0))
# make the root window the size of the image
#root.geometry("%dx%d+%d+%d" % (325, 475, x+100, y+100))
# remove tk icon
LoginErrorMsg.wm_iconbitmap('Ethicsicon.ico')
#if user closes Error Message Window, clean up memory
LoginErrorMsg.protocol("WM_DELETE_WINDOW", handler)
# root has no image argument, so use a label as a panel
panel1 = tk.Label(LoginErrorMsg, text="\nYou have exceeded three (3) login attempts.", background = "white", borderwidth = 0)
#panel1.configure(background = 'white')
panel1.pack(side='top', fill='both', expand='yes')
panel2 = tk.Label(LoginErrorMsg, image=image1, background = "white", borderwidth = 0)
panel2.pack(side='top', fill='both', expand='yes')
panel3 = tk.Label(LoginErrorMsg, text="", borderwidth = 0)
panel3.pack(side='top', fill= 'both', expand='yes')
# save the panel's image from 'garbage collection'
panel1.image = image1
# put a button on the image panel
button2 = tk.Button(panel3, text = ' OK ', command = LeaveSystemCallback)
button2.pack(side='top')
LoginErrorMsg.update()

Try changing the highlightthickness attribute of each label to zero.

Related

Problem with images overlapping in pygame

Im having problems with blitting images to rect objects in pygame. i have a background image blitted to my main pygame window, and also an image blitted to a rect object on the screen which moves. the problem i am having is the rect object is overlapping my background image when its moving around. i was looking to only be able to see the green helicopter shape and not the black outline around it. sorry if i havent explained this very well. will try to include all files im using.
Thanks for any help
import pygame as pg
import random as r
import time
pg.init()
MAX_X = 1190
MAX_Y = 590
MIN_X = 10
MIN_Y = 10
SIZE = 100
SPEED = 1
COLOR = (0,255,0)
move_amount = 0
wn = pg.display.set_mode((1200, 600))
BG_IMG = pg.image.load('bg.png').convert()
BG_IMG = pg.transform.scale(BG_IMG, (1200, 600))
class Wall (pg.Rect):
def __init__(self, posX, posY):
self.xcor = posX
self.ycor = posY
self.rect = None
class Heli (pg.Rect):
def __init__(self, posX, posY):
self.image = pg.image.load('art.png').convert()
self.rect = self.image.get_rect()
self.xcor = posX
self.ycor = posY
# top and bottom constant walls
TOP = pg.Rect(MIN_X, MIN_Y, MAX_X, 3)
BOTTOM = pg.Rect(MIN_X, MAX_Y, MAX_X, 3)
heli = Heli(MIN_X, MAX_Y //2)
# keep moving walls in a list
moving_walls = [Wall(MAX_X, r.randint((MIN_Y + 10), (MAX_Y - 10)))]
# main loop
while True:
# fill screen
wn.fill('black')
# editing objects to move
# blitting must happen before everything else
pg.draw.rect(wn,COLOR, heli.rect)
wn.blit(BG_IMG, (0,0))
wn.blit(heli.image, heli.rect)
heli.rect.y += move_amount
heli.rect.y += 1
# use a variable to control how much movement is happening
# movement happens continuosly
# if key down it oves if key up it doesnt
for wall in moving_walls :
wall.rect = pg.Rect(wall.xcor, wall.ycor, 3, SIZE)
pg.draw.rect(wn, COLOR, wall.rect)
wall.xcor -= SPEED
if wall.xcor < MIN_X + 10:
wall.xcor = MAX_X
wall.ycor = r.randint((MIN_Y), (MAX_Y - SIZE))
# drawing all objects back to the screen
pg.draw.rect(wn, COLOR, TOP)
pg.draw.rect(wn, COLOR, BOTTOM)
# update window
pg.display.update()
# event handling
for ev in pg.event.get():
if ev.type == pg.KEYDOWN:
if ev.key == pg.K_UP:
move_amount = -3
if ev.type == pg.KEYUP:
move_amount = 0
if ev.type == pg.QUIT:
pg.quit()
time.sleep(0.01)
You discard the transparency information of the image. You have to use convert_alpha instead of convert:
self.image = pg.image.load('art.png').convert()
self.image = pg.image.load('art.png').convert_alpha()
The pygame documentation notes that:
The returned Surface will contain the same color format, colorkey and alpha transparency as the file it came from. You will often want to call convert() with no arguments, to create a copy that will draw more quickly on the screen.
For alpha transparency, like in .png images, use the convert_alpha() method after loading so that the image has per pixel transparency.
See also How can I make an Image with a transparent Backround in Pygame?

How to resize an image with PIL getbbox to the maximum possible size?

I'm trying to resize sprites to a 96x96 boundary while retaining the aspect ratio.
The following code:
im.getbbox()
Returns a tuple containing the bounds of the sprite (original backgrounds are transparent), and I am stuck on this next part - I want to take that part of the image and resize it as large as it can possibly go within a 96x96 boundary
Here's an example of some sprites from Pokemon:
Since some are 80x80, some are 64x64, and the largest are 96x96, I would like to effectively select the contents of the sprite with im.getbbox() and then enlarge it to fit on top of a 96px white background.
Could anyone please help? I'm not sure how to maximise it within the bounds
My current code is as follows:
x = 0
for dirname, dirs, files in os.walk(path):
for filename in files:
x+=1
path = dirname + "/" + filename
print(path)
im = Image.open(path)
fill_color = (255,255,255)
im = im.convert("RGBA")
if im.mode in ('RGBA', 'LA'):
background = Image.new(im.mode[:-1], im.size, fill_color)
background.paste(im, im.split()[-1])
im = background
imResize = ImageOps.fit(im, (96, 96), Image.BOX, 0, (0.5, 0.5))
imResize.save("dataset/images/" + str(x) + '.png', 'PNG')
It takes the image and pastes it on to a white background and sets the size as 96px. This is fine for the native 96px images but the aspect ratio of the smaller images is ruined. By being able to enlarge them to the maximum bounds of a 96px image then it should prevent this from happening
Thanks!
ok, made my own pics, here:
zY28f_64.png, zY28f_80.png , zY28f_96.png
ended up with code :
from PIL import Image, ImageOps
import os
path= 'images'
x = 0
for dirname, dirs, files in os.walk(path):
for filename in files:
x+=1
path = dirname + "/" + filename
print(path)
im = Image.open(path)
im.show()
fill_color = (255,255,255)
im = im.convert("RGBA")
if im.mode in ('RGBA', 'LA'):
background = Image.new(im.mode[:-1], im.size, fill_color)
# background.paste(im, im.split()[-1])
background.paste(im)
im = background
im_inv = ImageOps.invert(im) ### make white background black
imResize = ImageOps.fit(im.crop(im_inv.getbbox()), (96, 96), Image.BOX, 0, (0.5, 0.5)) # im.crop crop on box got from image with black background, Image.getbbox works only with black bacground returning biggest box containing non zero(non black ) pixels
imResize.show()
# imResize.save("dataset/images/" + str(x) + '.png', 'PNG')
output:
zY28f_64.png2.png , zY28f_80.png1.png , zY28f_96.png3.png
main changes here:
make white background black
im_inv = ImageOps.invert(im)
im.crop crop on box got from image with black background, Image.getbbox works only with black background returning biggest box containing non zero(non black ) pixels
imResize = ImageOps.fit(im.crop(im_inv.getbbox()), (96, 96), Image.BOX, 0, (0.5, 0.5))
Since ImageOps.fit(...) line return chopped images, not sure how it works, to keep the entire figures I used code from PIL Image.resize() not resizing the picture to get:
from PIL import Image, ImageOps
import os
import math
path= 'images'
x = 0
for dirname, dirs, files in os.walk(path):
for filename in files:
x+=1
path = dirname + "/" + filename
print(path)
im = Image.open(path)
fill_color = (255,255,255)
im = im.convert("RGBA")
if im.mode in ('RGBA', 'LA'):
background = Image.new(im.mode[:-1], im.size, fill_color)
# background.paste(im, im.split()[-1])
background.paste(im)
im = background
im_inv = ImageOps.invert(im)
imResize = im.crop(im_inv.getbbox())
width, height = imResize.size
print(width, height)
if height > width:
ratio = math.floor(height / width)
newheight = ratio * 96
print(imResize, ratio, newheight)
imResize = imResize.resize((96, newheight))
else:
ratio = math.floor(width /height )
newwidth = ratio * 96
print(imResize, ratio, newwidth)
imResize = imResize.resize((newwidth, 96))
imResize.show()
print(imResize.size)
imResize.save(path + str(x) + '.png', 'PNG')
output:
zY28f_64.png2.png , zY28f_80.png1.png , zY28f_96.png3.png

Godot how to center text on label?

I just made a new Godot project and created a Label with text. Even with Align: center the text stays top left when I run the game.
Label.tscn
[gd_scene format=2]
[node name="Label" type="Label" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 40.0
margin_bottom = 14.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 2
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 4
text = "heylab"
align = 1
valign = 1
percent_visible = 1.0
lines_skipped = 0
max_lines_visible = -1
_sections_unfolded = [ "Anchor" ]
After setting Align and Valign to Center, you have to adjust both anchors and margins. You have some different options to do that.
Choosing "Center" in Layout will center your label by adjusting anchors to 0.5 (center of screen), and will calculate Margins, so that the Rect will be centered (without changing its size).
Choosing "Full Rect" in Layout will set anchor to (0, 0, 1, 1, that is the full screen), margins to 0, and will change the Rect of your Label node, so that the node will fill the screen.
The Layout button appears in the toolbar when you select Control nodes (Labels, Containers etc).
screenshot to show Layout button in Godot 3
Obs.: It's probably better to first create a Container node, set Container node to Full Rect, then create child nodes for your label. Your anchors are set inside the parent's Rect.
Just set the Align and Valign properties to Center to center the text. The bounding rect of the label has to be scaled to actually see the effect. You can do that by dragging the control points of the rect in the 2D view or change the "Margin" or "Size" of the rect in the "Control" section of the inspector.

Changing a part of an image

How can I paste back a part of my picture after I changed it in MATLAB? I cropped the plates off this image of a car and now I want to put it back automatically. The plates are still at the same coordinates as they were initially, but the background is all black.
The car I want to paste on:
And this is what I want to paste:
Here is my code, I want to change the part where I need to draw by hand the plate.
fontSize = 20;
format compact;
baseFileName1 = 'blurr_plate.jpg';
baseFileName2 = 'car2.jpg';
sourceImage = imread(baseFileName1);
subplot(1, 2, 1);
imshow(sourceImage);
axis on;
caption = sprintf('Source image, %s', baseFileName1);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst','numbertitle','off')
targetImage = imread(baseFileName2);
subplot(1, 2, 2);
imshow(targetImage);
axis on;
caption = sprintf('Target image, %s, original', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
% Ask user to draw freehand mask.
message = sprintf('In the LEFT IMAGE...\nLeft click and hold to begin drawing.\nSimply lift the mouse button to finish');
subplot(1, 2, 1);
uiwait(msgbox(message));
hFH = imfreehand(); % Actual line of code to do the drawing.
% Create a binary image ("mask") from the ROI object.
mask = hFH.createMask();
xy = hFH.getPosition;
% Paste it onto the target image.
targetImage(mask) = sourceImage(mask);
% Display new image.
subplot(1, 2, 2); % Switch active axes to right hand axes.
imshow(targetImage);
imwrite(targetImage, 'car_new.jpg')
axis on;
caption = sprintf('Target image, %s, after paste', baseFileName2);
title(caption, 'FontSize', fontSize, 'Interpreter', 'none');
Your code will work only in case when both source and target images are grayscale. As your target image is coloured, make following changes:
Delete line number 35,36 and 41.
paste this code after line 33.
redChannel = targetImage(:, :, 1);
greenChannel = targetImage(:, :, 2);
blueChannel = targetImage(:, :, 3);
redChannel(mask) = sourceImage(mask);
greenChannel(mask) = sourceImage(mask);
blueChannel(mask) = sourceImage(mask);
targetImage = cat(3, redChannel, greenChannel, blueChannel);

Adjust Image on button

How can I adjust an image to a button in Tkinter?
Actually i have this :
originalImg = Image.open(currentphotofolderPath + file)
img = ImageTk.PhotoImage(originalImg)
Button(photoFrame, image = img, borderwidth=0, height = 200, width = 200)
The problem the image does not adjust to the button with 200x200
I don't want to resize the image with PhotoImage.resize()
The zoom() function should fix your issue:
Return a new PhotoImage with the same image as this widget but zoom it
with X and Y.
Adding the code line below before instantiating the Button() widget should be helpful:
originalImg = Image.open(currentphotofolderPath + file)
originalImg.zoom(200, 200)
img = ImageTk.PhotoImage(originalImg)
Button(photoFrame, image=img, borderwidth=0, height=200, width=200)
you have a couple of choices, the zoom function as posted by Billal, or you create a resize function:
def Resize_Image(image, maxsize):
r1 = image.size[0]/maxsize[0] # width ratio
r2 = image.size[1]/maxsize[1] # height ratio
ratio = max(r1, r2)
newsize = (int(image.size[0]/ratio), int(image.size[1]/ratio))
image = image.resize(newsize, Image.ANTIALIAS)
return image
which will then resize the Image (not the PhotoImage) to the biggest possible size while retaining the aspect ratio (without knowing it beforehand)
note that the resize method should use less memory than the zoom method (if thats an important factor)

Resources