Dan Shorla Ki
Dan Shorla Ki

Reputation: 125

Is there a way of displaying a 16-bit image in Tkinter?

I got a single-layer uint16 tiff image, i.e 2d array each value ranges between 0-65355. When I read and display the image with cv2 it works corrrectly.

im = cv2.imread(path, -1)
cv2.imshow('im', im)

Now I'm trying to make a GUI with Tkinter and incorporate the image into the GUI, but all it displayed is a white canvas.

im = cv2.imread(path, -1)
height = im.shape[0]
width = im.shape[1]
canvas.config(width=width, height=height)
image = Image.fromarray(im)
root.photo = photo = ImageTk.PhotoImage(image=image)
canvas.create_image(0, 0, image=photo, anchor=tk.NW)

Other types of RGB 8bit images are displyed as shuold. How can I disply the image? what Im doing wrong?

Upvotes: 0

Views: 939

Answers (1)

CmdrTrip
CmdrTrip

Reputation: 11

I have had the same issue as of late without a solution. This is what I believe is causing the issue.

Your image mode is type I;16L, but when you call ImageTk.PhotoImage‍ the constructor checks if the type is among the types ["1", "L", "RGB", "RGBA"]. Since it is not, it gets the base mode of your type (in my case it was 'L') and converts to that base in the paste function of the PhotoImage class.

I do not know how to stop/bypass this conversion, so what I plan to do is show approximate versions of the images. I will take my images and convert to a standard 8-bit RGB then show that in the Tkinter GUI, but any manipulations will be made to the original images.

Edit: My Work Around/Solution

Because my image is type I;32L, I used OpenCV to open my image and NumPy to convert it to the appropriate type. Here's my example:

my_image = cv2.imread("image.tiff") # read in the image with OpenCV
my_image = np.uint8(my_image) # convert image into an unsigned 8 bit int array with NumPy
my_image = Image.fromarray(my_image) # read in image from array with Tkinter
rendered_image = ImageTk.PhotoImage(my_image) # create the photo image for display

Upvotes: 1

Related Questions