调整图片大小以适应画布尺寸

0 投票
2 回答
12411 浏览
提问于 2025-04-18 00:15

有没有人能帮我用ImageTk来调整图片大小?

我有一个画布,打算在上面放图片。

我有不同种类的图片,大小各不相同。

当我把一张图片放到画布上时,我希望这张图片的大小能调整到适合画布,并且保持原来的比例。

请帮帮我!我对PIL、Tkinter和Python都很陌生。

更新:

我尝试使用thumbnail这个方法,但在调整大小时:

self.image.thumbnail(self.picsize,Image.ANTIALIAS)

图片没有适应画布的大小,如果图片比画布长或宽,就会被裁掉。(没有调整到适合画布的大小)


代码:

from PIL import ImageTk
from Tkinter import *
import os,tkFileDialog,Image

picsize = 250,250 # I want to set this so that it will fit in the self.imagecanvas | Every images attached will share same Size
imagepath = "Default_ProPic.jpg"
class GUI():
    global picsize
    def display(self):
        self.canvas = Canvas(width=1200,height=700)
        self.canvas.pack()
    
        self.imagecanvas = Canvas(self.canvas,width=400,height=400)
        self.imagecanvas.place(x=980,y=180)
        self.image = Image.open(imagepath)
        self.image.thumbnail(picsize,Image.ANTIALIAS)
        self.newimage = ImageTk.PhotoImage(self.image)
        self.profile_picture=self.imagecanvas.create_image(0,0,anchor = NW,image=self.newimage)
    
        attachbutton = Button(self.canvas,text="       Profile Pic       ",command=lambda:self.attachpic())
        attachbutton.place(x=1030,y=320)
    
        mainloop()

    def attachpic(self):
        global picsize
        attachphoto = tkFileDialog.askopenfilename(title="Attach photo")
        self.image = Image.open(attachphoto)
        self.image.thumbnail(picsize,Image.ANTIALIAS)
        self.newimage = ImageTk.PhotoImage(self.image)
        self.imagecanvas.itemconfigure(self.profile_picture, image=self.newimage)
    
GUI = GUI()
GUI.display()

上面使用的图片:在这里输入图片描述

2 个回答

0

你只需要找出一个合适的大小,让它可以在窗口里显示,并且

  • 确保内容不会超出窗口的边界,
  • 同时保持原来的宽高比例。

幸运的是,这个过程并不复杂。

 def best_fit(oldsize, picsize):
    new_width, new_height = picsize
    old_width, old_height = oldsize
    # if new_width/old_width < new_height/old_height is mathematically the same as
    if new_width * old_height < new_height * old_width:
        # reduce height to keep original aspect ratio
        new_height = max(1, old_height * new_width // old_width)
    else:
        # reduce width to keep original aspect ratio
        new_width = max(1, old_width * new_height // old_height)
    return (new_width, new_height)

siz = self.image.size
self.image = self.image.resize(best_fit(siz, picsize), Image.ANTIALIAS)

这里的 max 函数是用来防止宽度和高度变成零的。

0

试着把缩略图单独保存为一个变量:

self.thmb_img = self.image.thumbnail(picsize, Image.ANTIALIAS)

我怀疑它可能在使用原始的 self.image = Image.open(attachphoto)

我建议你观察一下尺寸是怎么变化的:

def attachpic(self):
    picsize = 250, 250
    attachphoto = tkFileDialog.askopenfilename(title="Attach photo")
    self.image = Image.open(attachphoto)
    print self.image.size()
    self.thmb_img = self.image.thumbnail(picsize,Image.ANTIALIAS)
    print self.thmb_img.size()

检查输出的大小,确认它和原始图片以及你想要的(250, 250)缩略图是一样的。

撰写回答