How to convert ImageTk to Image?

python-3.x, python-imaging-library, tkinter

Solution

Ok, that was not easy but I think I have a solution though you need to go into some private methods of `label.image`. Maybe there is a better way if so I would love to see.

import tkinter as tk
from tkinter import Label
import numpy as np
from PIL import Image, ImageTk

root = tk.Tk()

# create label1 with an image
image = Image.open('pic1.jpg')
image = image.resize((500, 750), Image.ANTIALIAS)
picture = ImageTk.PhotoImage(image=image)
label1 = Label(root, image=picture)
label1.image = picture

# extract rgb from image of label1
width, height = label1.image._PhotoImage__size
rgb = np.empty((height, width, 3))
for j in range(height):
    for i in range(width):
        rgb[j, i, :] = label1.image._PhotoImage__photo.get(x=i, y=j)

# create new image from rgb, resize and use for label2
new_image = Image.fromarray(rgb.astype('uint8'))
new_image = new_image.resize((250, 300), Image.ANTIALIAS)
picture2 = ImageTk.PhotoImage(image=new_image)
label2 = Label(root, image=picture2)
label2.image = picture2

# grid the two labels
label1.grid(row=0, column=0)
label2.grid(row=0, column=1)

root.mainloop()

Actually you can zoom and reduce the original picture by using the methods `zoom` to enlarge the picture (`zoom(2)` doubles the size) and `subsample` to reduce the size (`subsample(2)` halves the picture size).

for example

picture2 = label1.image._PhotoImage__photo.subsample(4)

reduces the size of the picture to a quarter and you can skip all the conversion to an Image.

According to `label1.image._PhotoImage__photo.subsample.__doc__`:

Return a new PhotoImage based on the same image as this widget but use only every Xth or Yth pixel. If y is not given, the default value is the same as x

and `label1.image._PhotoImage__photo.zoom.__doc__`:

Return a new PhotoImage with the same image as this widget but zoom it with a factor of x in the X direction and y in the Y direction. If y is not given, the default value is the same as x.

Problem

Let's say I have some `ImageTk.PhotoImage` image stored in the variable `imgtk`. How can I convert it back to an `Image.Image`? The reason is that I want to resize it, but it seems that `.resize()` only works for `Image.Image`s.

Original source