Python 在PhotoImage下调整图像大小

Python 在PhotoImage下调整图像大小,python,tkinter,Python,Tkinter,我需要调整图像的大小,但我想避免PIL,因为我不能让它在OSX下工作-不要问我为什么 无论如何,由于我对gif/pgm/ppm感到满意,PhotoImage类对我来说还可以: photoImg = PhotoImage(file=imgfn) images.append(photoImg) text.image_create(INSERT, image=photoImg) 问题是-如何调整图像的大小? 以下仅适用于PIL,这是非PIL等效物 img = Image.open(imgfn) im

我需要调整图像的大小,但我想避免PIL,因为我不能让它在OSX下工作-不要问我为什么

无论如何,由于我对gif/pgm/ppm感到满意,PhotoImage类对我来说还可以:

photoImg = PhotoImage(file=imgfn)
images.append(photoImg)
text.image_create(INSERT, image=photoImg)
问题是-如何调整图像的大小? 以下仅适用于PIL,这是非PIL等效物

img = Image.open(imgfn)
img = img.resize((w,h), Image.ANTIALIAS)
photoImg = ImageTk.PhotoImage(img)
images.append(photoImg)
text.image_create(INSERT, image=photoImg) 

谢谢大家!

您必须使用
PhotoImage
类的
subsample()
zoom()
方法。对于第一个选项,您首先必须计算比例因子,以下几行简单说明:

scale_w = new_width/old_width
scale_h = new_height/old_height
photoImg.zoom(scale_w, scale_h)
因为
zoom()
subsample()
都需要整数作为参数,所以我使用了这两个参数

我不得不将320x320图像调整为250x250,结果是

imgpath = '/path/to/img.png'
img = PhotoImage(file=imgpath)
img = img.zoom(25) #with 250, I ended up running out of memory
img = img.subsample(32) #mechanically, here it is adjusted to 32 instead of 320
panel = Label(root, image = img)

我也有同样的问题,我发现@Memes的答案相当有效。只需确保尽可能降低您的比率,因为由于某些原因,
subsample()
需要相当长的时间才能运行

基本上,图像被缩小到两种尺寸中最小的公因子,然后由原始尺寸进行补偿。这将为您留下所需大小的映像。

如果您没有安装PIL-->请安装它 (对于Python3+用户-->在cmd中使用“pip安装枕头”)
我有一个要求,我想打开一个图像,调整它的大小,保持纵横比,用一个新名称保存它,并在tkinter窗口中显示它(使用LinuxMint)。在浏览了几十个论坛问题并处理了一些奇怪的错误(似乎涉及到Python 3.x中的PIL to Pillow fork)之后,我能够开发一些有效的代码,使用预定义的新最大宽度或新最大高度(根据需要放大或缩小)和画布对象,其中图像显示在帧的中心位置。请注意,我没有包括文件对话框,只是为一个文件打开并保存一个硬编码图像:

from tkinter import *
from PIL import ImageTk, Image
import shutil,os
from tkinter import filedialog as fd

maxwidth = 600
maxheight = 600

mainwindow = Tk()
picframe = Frame(mainwindow)
picframe.pack()
canvas = Canvas(picframe, width = maxwidth, height = maxheight)  
canvas.pack()

img = Image.open("/home/user1/Pictures/abc.jpg")

width, height = img.size                # Code to scale up or down as necessary to a given max height or width but keeping aspect ratio
if width > height:
    scalingfactor = maxwidth/width
    width = maxwidth
    height = int(height*scalingfactor)
else:
    scalingfactor = maxheight/height
    height = maxheight
    width = int(width*scalingfactor)

img = img.resize((width,height), Image.ANTIALIAS)

img.save("/home/user1/Pictures/Newabc.jpg")

img = ImageTk.PhotoImage(img)     # Has to be after the resize
canvas.create_image(int(maxwidth/2)-int(width/2), int(maxheight/2)-int(height/2), anchor=NW, image=img)   # No autocentering in frame, have to manually calculate with a new x, y coordinate based on a NW anchor (upper left)

我需要什么!唯一的问题是,zoom()需要整数参数,这有点奇怪,因为我可能想将其从640x480重新缩放到320x240:在这种情况下,我将得到zoom(0,0)。或者放大一个小的因子,小于2x,那么我想你必须使用
子样本
方法。我想它必须这样做!刚刚发现,使用单一的调整大小方法可能更方便一些,但Tk设计师没有想到这一点(如果需要,请使用PIL)在
AttributeError:“PhotoImage”对象没有属性“zoom”
@markroxor PIL的
PhotoImage
没有实现Tkinter的
PhotoImage
中的
zoom
(以及其他一些方法)
AttributeError:“PhotoImage”对象没有属性“zoom”
from tkinter import *
from PIL import ImageTk, Image
import shutil,os
from tkinter import filedialog as fd

maxwidth = 600
maxheight = 600

mainwindow = Tk()
picframe = Frame(mainwindow)
picframe.pack()
canvas = Canvas(picframe, width = maxwidth, height = maxheight)  
canvas.pack()

img = Image.open("/home/user1/Pictures/abc.jpg")

width, height = img.size                # Code to scale up or down as necessary to a given max height or width but keeping aspect ratio
if width > height:
    scalingfactor = maxwidth/width
    width = maxwidth
    height = int(height*scalingfactor)
else:
    scalingfactor = maxheight/height
    height = maxheight
    width = int(width*scalingfactor)

img = img.resize((width,height), Image.ANTIALIAS)

img.save("/home/user1/Pictures/Newabc.jpg")

img = ImageTk.PhotoImage(img)     # Has to be after the resize
canvas.create_image(int(maxwidth/2)-int(width/2), int(maxheight/2)-int(height/2), anchor=NW, image=img)   # No autocentering in frame, have to manually calculate with a new x, y coordinate based on a NW anchor (upper left)