Adjust Image on button - image

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)

Related

How to set background size cover on a canvas

I'm using a canvas to make blur effect on boostrap carousel images. Basically, carousel images are set to background size cover so image will crop according to window size. I want to do the same to the canvas image. Any ideas? Thanks heaps!
This snippet should do the trick.
var aspectheight = h * (canvas.width / w);
var heigthoffset = ((aspectheight - canvas.height) / 2) * -1;
ctx.drawImage(image, 0, heigthoffset, canvas.width, aspectheight);
Where h and w are the width and height if the image being rendered, and image is that image.

Resize an image along rows only or columns only in matlab

I'm writing a function in matlab to zoom or shrink an image using bicubic interpolation. However, my function resizes an image along both rows and columns. What if I want to enlarge the image along the rows only, or along the columns only? This is my code so far
function pic_new = zoom_image(pic, zoom_value)
actualSize = size(pic);
newSize = max(floor(zoom_value.*actualSize(1:2)),1);
newX = ((1:newSize(2))-0.5)./zoom_value+0.5; %# New image pixel X coordinates
newY = ((1:newSize(1))-0.5)./zoom_value+0.5;
oldClass = class(pic); %# Original image type
pic = double(pic); %# Convert image to double precision for interpolation
if numel(actualSize) == 2
pic_new = interp2(pic,newX,newY(:),'cubic');
end
pic_new = cast(pic_new,oldClass);
end
Updated: I was able to resize the image both along rows and columns. However, it doesn't work right
This is the original image: https://imagizer.imageshack.us/v2/895x383q90/r/903/4jM76I.png
This is the image after being enlarge 2.5 along rows and shrunk 1.3 along columns: https://imagizer.imageshack.us/v2/323x465q90/r/673/EHIaoB.png
Why is there such a black box in the result image?
Updated 2: This is how I did: in the command window type
>> img = imread('pic.pgm');
>> newImage = zoom_image(img, 2.5, 1/1.3);
>> imshow(newImage)
Using imresize it can be easily achieved
pic_new = imresize( pic, newSize, 'bicubic' );
Where newSize is the new size of the image (height and width). The new aspect ratio can be arbitrary and does not have to be the same as the aspect ratio of the new image.
For example, shrinking an image by 1/2 along the rows and leaving number of columns unchanged:
[nCol nRows] = size( pic(:,:,1) );
pic_new = imresize( pic, [nCols round( nRows/2 ) ], 'bicubic' );
Try editing your function to have a separate zoom for rows and columns, a la
function pic_new = zoomfunc(pic, zoom_valueX, zoom_valueY)
actualSize = size(pic);
newSize = max(floor([zoom_valueY zoom_valueX].*actualSize(1:2)),1);
newX = ((1:newSize(2))-0.5)./zoom_valueX+0.5; %# New image pixel X coordinates
newY = ((1:newSize(1))-0.5)./zoom_valueY+0.5;
oldClass = class(pic); %# Original image type
pic = double(pic); %# Convert image to double precision for interpolation
if numel(actualSize) == 2
pic_new = interp2(pic,newX,newY(:),'cubic');
end
pic_new = cast(pic_new,oldClass);
end

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

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.

Scaling an image proportionally based on the image's dimensions and my restriction size

Looking for an expression that allows me to accomplish this:
I have an image of arbitrary width/height, whose dimensions I can grab before I draw it.
Because the image may be very large, I want to scale it down.
My canvas is going to have width w and height h.
For illustration purposes let's just say it's 320x240.
If the dimensions of the image are equal or smaller than the dimensions of the canvas, then the scale ratio is just 1.
If they are larger, I will scale it proportional to how much larger it is compared to the canvas size.
So for example if my image is 640x480, my scale ratio will be 0.5
If my image is 640x240, my scale ratio would still be 0.5
Similarly if it were 320x480
Can this be written in a single math expression? For ex:
def scale_ratio(canvas_width, canvas_height, image_width, image_height)
#math formula for calculating scale
return scale
function scale(canvas_width, canvas_height, image_width, image_height) {
return Math.min(Math.max(canvas_width / image_width, canvas_height / image_height), 1);
}
EDIT: You might want to do something like this to reduce rounding errors:
var scale_width = image_width;
var scale_height = image_height;
if (image_width > canvas_width || image_height > canvas_height) {
var image_ratio = image_height / image_width;
if (image_ratio * canvas_width > canvas_height) {
scale_width = canvas_height / image_ratio;
scale_height = canvas_height;
} else {
scale_width = canvas_width;
scale_height = image_ratio * canvas_width;
}
}

Resize image for Live Tile - WriteableBitmapEx

**
Found the solution
Because of the fact this is a tile, the image will always be strechted to 173 by 173!
To avoid this first create a dummy 173 by 173 and merge this with the resized one!
Rect rect = new Rect(0.0, 0.0, width, height);
WriteableBitmap bitmapDummy = new WriteableBitmap(173, 173);
bitmapDummy.Blit(rect, resized, rect, WriteableBitmapExtensions.BlendMode.None);
**
Well I have created a Background agent to update the live tile of my WP7 app.
But no matter what I try to resize it, I'm not getting a good result!
Any tips? Currently I have following code, but I also tried 135 by 173 and also the other Interpolation.
WriteableBitmap writeableBitmap = new WriteableBitmap(bitmapImage);
var resized = writeableBitmap.Resize(173, 173, System.Windows.Media.Imaging.WriteableBitmapExtensions.Interpolation.Bilinear);
There is also a small rectangle added below to show the title of the app! It's 40px in height, would be great if image would be cropped above.
The actual image is always 250 by 321px
Your problem is that you're not calculating the width/heights to a correct Aspect ratio.
So to get a 1:1 proportions, you would need a width of 134.735 pixels, for a 173 pixel height.
This can be done by first determining what side is the largest
var aspect = Math.Max(bitmapImage.Width, bitmapImage.Height)
var ratio = largest / 173;
var width = width / ratio;
var height = height / ratio;
var resizedImage = writeableBitmap.Resize(width, height, System.Windows.Media.Imaging.WriteableBitmapExtensions.Interpolation.Bilinear);
And remember to set Stretch="Uniform" to avoid stretching the image to unnecessary proportions.
To create a 173x173 pixel image, with the other image applied on top, use the Blit function from WriteableBitmapEx
var tileImage = new WriteableBitmap(173, 173, ...)
tileImage.Blit(new Rect(width, height), resizedImage, new Rect(width, height), BlendMode.None);

Resources