如何在Tkinter中显示极长的图像?(如何避开画布最大限制) [英] How do I display an extremly long image in Tkinter? (how to get around canvas max limit)
问题描述
我尝试了多种使用tkinter显示大图像的方法真正的长图像无论我尝试了什么,似乎都没有任何有效的代码.主要问题是Canvas的最大高度限制为30,000像素左右.
I've tried multiple ways of displaying large images with tkinterreally long image No matter what I've tried, there doesn't seem to be any code that works. The main issue is that Canvas has a maximum height limit of around 30,000 pixels.
有没有办法显示整个图像?增加,还是绕过画布极限?请参见下面的示例图片.
Is there a way to display this whole image? increase, or get around the canvas limit? See the example image below.
推荐答案
这是一个不太吸引人的答案,但答案仍然如此.这将极长的图像划分为1000个像素长度的平铺".它不划分宽度.我将来自多个来源的代码拼接在一起,直到我将其全部工作为止.如果有人可以使用滚动条功能来做到这一点,那将很酷.
This is a rather unattractive answer, but an answer non-the-less. This divides up extremely long images into "tiles" of 1000 pixel lengths. It does not divide the width. I've spliced together code from several sources until I got it all to work. If someone could make this with a scroll-bar functionality, that would be cool.
from tkinter import *
from PIL import ImageTk as itk
from PIL import Image
import math
import numpy as np
Image.MAX_IMAGE_PIXELS = None #prevents the "photo bomb" warning from popping up. Have to have this for really large images.
#----------------------------------------------------------------------
# makes a simple window with a button right in the middle that let's you go "down" an image.
class MainWindow():
#----------------
def __init__(self, main):
# canvas for image
_, th, tw, rows, cols = self.getrowsandcols()
self.canvas = Canvas(main, width=tw, height=th)
#self.canvas.grid(row=0, column=0)
self.canvas.pack()
# images
self.my_images = self.cropimages() # crop the really large image down into several smaller images and append to this list
self.my_image_number = 0 #
# set first image on canvas
self.image_on_canvas = self.canvas.create_image(0, 0, anchor = NW, image = self.my_images[self.my_image_number])
# button to change image
self.upbutton = Button(main, text="UP", command=self.onUpButton)
self.downbutton = Button(main, text="DOWN", command=self.onDownButton)
self.upbutton.pack()
self.downbutton.pack()
#self.downbutton.grid(row=1, column=0)
#self.upbutton.grid(row=1, column=0)
#----------------
def getimage(self):
im = Image.open("Test_3.png") # import the image
im = im.convert("RGBA") # convert the image to color including the alpha channel (which is the transparency best I understand)
width, height = im.size # get the width and height
return width, height, im # return relevent variables/objects
def getrowsandcols(self):
width, height, im = self.getimage()
im = np.asarray(im) # Convert image to Numpy Array
tw = width # Tile width will equal the width of the image
th = int(math.ceil(height / 100)) # Tile height
rows = int(math.ceil(height / th)) # Number of tiles/row
cols = int(math.ceil(width / tw)) # Number of tiles/column
return im, th, tw, rows, cols #return selected variables
def cropimages(self):
self.my_images = [] # initialize list to hold Tkinter "PhotoImage objects"
im, th, tw, rows, cols = self.getrowsandcols() # pull in needed variables to crop the really long image
for r in range(rows): # loop row by row to crop all of the image
crop_im =im[r * th:((r * th) + th), 0:tw] # crop the image for the current row (r). (th) stands for tile height.
crop_im = Image.fromarray(crop_im) # convert the image from an Numpy Array to a PIL image.
crop_im = itk.PhotoImage(crop_im) # convert the PIL image to a Tkinter Photo Object (whatever that is)
self.my_images.append(crop_im) # Append the photo object to the list
crop_im = None
return self.my_images
def onUpButton(self):
# next image
if self.my_image_number == 0:
self.my_image_number = len(self.my_images)-1
else:
self.my_image_number -= 1 # every button pressed will
# change image
self.canvas.itemconfig(self.image_on_canvas, image=self.my_images[self.my_image_number]) # attaches the image from the image list to the canvas
def onDownButton(self):
# next image
self.my_image_number += 1 #every button pressed will
# return to first image
if self.my_image_number == len(self.my_images):
self.my_image_number = 0
# change image
self.canvas.itemconfig(self.image_on_canvas, image = self.my_images[self.my_image_number]) #attaches the image from the image list to the canvas
#----------------------------------------------------------------------
root = Tk()
MainWindow(root)
root.mainloop()
这篇关于如何在Tkinter中显示极长的图像?(如何避开画布最大限制)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!