英文:
Resizing PIL rgb image in tkinter application
问题
背景
我正在创建一个小型幻灯片应用程序,允许显示图像。原始图像相当大(2000x2000像素),因此我希望将其重新调整大小以适应屏幕。这方面的工作如预期一样进行。
该图像本质上是一个数组,值范围从0到16位。为了让PIL显示颜色,我复制该数组,分别处理每个通道,转换为图像对象,重新调整大小并显示。在这里,重新调整大小似乎无法正常工作。
方法
我在下面分享了一个重现这个问题的最简代码版本,至少在我的系统上是这样的。
import tkinter as tk
import numpy as np
from PIL import Image, ImageTk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.images = {}
self.load_image()
self.show_image()
def load_image(self):
img = np.zeros((2000,2000))
img[100:800, 100:800] = 255
self.images[0] = img
def show_image(self):
img = self.images[0]
img = np.repeat(img[:,:,np.newaxis], 3, axis=2)
img = Image.fromarray(img, 'RGB')
img = img.resize((1000,1000))
img = ImageTk.PhotoImage(img)
self.persistent_img = img
self.canvas = tk.Canvas(self.parent, height=1000, width=1000)
self.canvas.grid(row=0, column=0)
self.canvas.create_image(0,0,anchor='nw', image=img)
if __name__ == '__main__':
root = tk.Tk()
MainApplication(root)
root.mainloop()
预期
实际上,如果只重新调整大小单通道图像,则上述代码可以正常工作:
img = np.zeros((2000,2000))
img[100:800, 100:800] = 255
self.images[0] = img
[...]
img = self.images[0]
img = Image.fromarray(img)
img = img.resize((1000,1000))
[...]
实际
这是什么原因,有没有解决方法?非常感谢您的帮助!
英文:
background
I am creating a small slideshow application that allows for displaying an image. The original image is quite large (2000 by 2000 pixels), so I want to rescale it to fit the screen. This works as expected.
The image is essentially an array, with values ranging from 0 to 16 bit.
To get PIL to display colours, I triplicate the array, manipulate each channel individually, convert to an Image object, rescale and display. Here, the rescaling does not seem to work properly.
approach
I am sharing a barebones version of my code that repoduces this issue, at least on my system.
import tkinter as tk
import numpy as np
from PIL import Image, ImageTk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.images = {}
self.load_image()
self.show_image()
def load_image(self):
img = np.zeros((2000,2000))
img[100:800, 100:800] = 255
self.images[0] = img
def show_image(self):
img = self.images[0]
img = np.repeat(img[:,:,np.newaxis], 3, axis=2)
img = Image.fromarray(img, 'RGB')
img = img.resize((1000,1000))
img = ImageTk.PhotoImage(img)
self.persistent_img = img
self.canvas = tk.Canvas(self.parent, height=1000, width=1000)
self.canvas.grid(row=0, column=0)
self.canvas.create_image(0,0,anchor='nw', image=img)
if __name__ == '__main__':
root = tk.Tk()
MainApplication(root)
root.mainloop()
expected
In fact, this works with the code above, if I just rescale the one-channel image:
img = np.zeros((2000,2000))
img[100:800, 100:800] = 255
self.images[0] = img
[...]
img = self.images[0]
img = Image.fromarray(img)
img = img.resize((1000,1000))
[...]
actual
What is causing this, and is there a way around? Help is highly appreciated!
答案1
得分: 2
应该在np.zeros(...)
中设置dtype=uint8
以用于图像数据:
np.zeros((2000, 2000), dtype=np.uint8)
英文:
Should set dtype=uint8
in np.zeros(...)
for image data:
np.zeros((2000, 2000), dtype=np.uint8)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论