如何为特大图像增加Tkinter最大画布大小? [英] How can I increase Tkinter Maximum Canvas size for extremely large images?

查看:150
本文介绍了如何为特大图像增加Tkinter最大画布大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我显示的图像(高度)不能超过30612像素高。我了解到画布的最大高度。我想获取源文件并将其扩展到90或100k像素的高度。相反,我看到有人建议可以缓冲画布,如果这是真的,我不知道如何实现它。任何帮助都将受到赞赏!

I can't display images longer (height) than about 30612 pixels high. I've read that there is a maximum height to canvas. I'd like to get the source file and extend that to 90 or 100k pixels in height. Conversely, I've seen suggested that a canvas may be buffered, if this is true, I have no clue how to implement it.. Any help is appreciated!

I我正在使用我从Stack上发现的用于处理大图像的代码,它的确可以,但是最终达到了cavas的高度限制。
画布限制

I am using code I found off Stack that is supposed to deal with large images, it does alright, but ultimately hit's the cavas height limit. Canvas Limit

from tkinter import *
from PIL import ImageTk
from PIL import *

Image.MAX_IMAGE_PIXELS = None


class ScrolledCanvas(Frame):
    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        self.master.title("Spectrogram Viewer")
        self.pack(expand=YES, fill=BOTH)
        canv = Canvas(self, relief=SUNKEN)
        canv.config(width=400, height=500)
        # canv.config(scrollregion=(0,0,1000, 1000))
        # canv.configure(scrollregion=canv.bbox('all'))
        canv.config(highlightthickness=0)

        sbarV = Scrollbar(self, orient=VERTICAL)
        sbarH = Scrollbar(self, orient=HORIZONTAL)

        sbarV.config(command=canv.yview)
        sbarH.config(command=canv.xview)

        canv.config(yscrollcommand=sbarV.set)
        canv.config(xscrollcommand=sbarH.set)

        sbarV.pack(side=RIGHT, fill=Y)
        sbarH.pack(side=BOTTOM, fill=X)

        canv.pack(side=LEFT, expand=YES, fill=BOTH)
        self.im = Image.open("Test_3.tif")
        width, height = self.im.size
        canv.config(scrollregion=(0, 0, width, height))
        self.im2 = ImageTk.PhotoImage(self.im)
        self.imgtag = canv.create_image(0, 0, anchor="nw", image=self.im2)
ScrolledCanvas().mainloop()


推荐答案

这是我从多个来源获得的代码-感谢figbeam提供的所有帮助。另外,这还不漂亮!!!该按钮显示在Tkinter窗口的中央。

This is the code I've come up with from several sources - Thanks to figbeam for all the help. Also, this is not pretty!!!! The button shows up in the center of the Tkinter window. If you'd like to modify this, please do.

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)

        # 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.button = Button(main, text="DOWN", command=self.onDownButton)
        self.button.grid(row=0, 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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆