Как я могу повернуть изображение, загруженное с помощью filedialog.askopenfilename?

#python-3.x #tkinter

Вопрос:

Мне нужно просмотреть изображение и показать его, что я уже могу сделать. Я хотел бы повернуть это изображение на экране, нажав на кнопку, как я могу это сделать?

Это мой код:

 from tkinter import *
from PIL import ImageTk, Image
from tkinter import filedialog
import tkinter as tk


root = tk.Tk()
root.title('Exif Viewer')
root.geometry('500x550')
global image_loaded


def browse_image():
    global image_loaded

    root.filename = filedialog.askopenfilename(initialdir="/", title="Select An Image",
                                               filetypes=(("jpeg files", "*.jpeg"), ("png files", "*.png")))
    image_loaded = ImageTk.PhotoImage(Image.open(root.filename))
    image_loaded_label = Label(image=image_loaded).pack()


browse_button = Button(root, padx=20, pady=5, text="Load image", command=browse_image).pack()
rotate_left_button = Button(root, padx=10, pady=5, text="Rotate left").pack()
rotate_right_button = Button(root, padx=10, pady=5, text="Rotate right").pack()
exit_button = Button(root, padx=20, pady=5, text="Exit", command=root.quit).pack()


root.mainloop()
 

Большое спасибо

Комментарии:

1. Вы читали документацию по PIL и объекту изображения , прежде чем задавать этот вопрос?

2. Посмотри сюда

3. Да, я пробовал использовать эту функцию, но я не могу обновить представление

4. Пожалуйста, покажите, что вы пробовали. Код, который вы опубликовали, не показывает попыток поворота изображения.

5. Я попытался использовать функцию rotate(), но мне не удалось обновить представление метки.

Ответ №1:

Вы можете повернуть изображение с rotate помощью метода объекта изображения.

 def browse_image():
    global image_object, image_loaded_label

    root.filename = filedialog.askopenfilename(initialdir="/", title="Select An Image",
                                               filetypes=(("jpeg files", "*.jpeg"), ("png files", "*.png")))
    image_object = Image.open(root.filename)
    image_loaded = ImageTk.PhotoImage(image_object)
    image_loaded_label = Label(image=image_loaded)
    image_loaded_label.pack()
    image_loaded_label.image = image_loaded

def rotate_image(direction):
    global image_object
    angle = {"left":90, "right":-90}[direction]
    image_object = image_object.rotate(angle)
    rotated_tk = ImageTk.PhotoImage(image_object)
    image_loaded_label.config(image = rotated_tk)
    image_loaded_label.image = rotated_tk #Prevent garbage collection


browse_button = Button(root, padx=20, pady=5, text="Load image", command=browse_image).pack()
rotate_left_button = Button(root, padx=10, pady=5, text="Rotate left", command = lambda: rotate_image("left")).pack()
rotate_right_button = Button(root, padx=10, pady=5, text="Rotate right", command = lambda: rotate_image("right")).pack()
exit_button = Button(root, padx=20, pady=5, text="Exit", command=root.quit).pack()
 

Для того, чтобы использовать объект изображения, он находится в отдельной строке к фотоизображению и называется image_object . image_loaded_label.image Строка предназначена для предотвращения сбора мусора, что приведет к тому, что изображение не появится.
Я добавил команды к обеим кнопкам, которые вызывают rotate_image . При этом в качестве параметра принимается направление, которое затем преобразуется в число градусов против часовой стрелки для поворота изображения. rotate Метод image_object используется для поворота изображения , которому затем присваивается image_object , заменяя исходный объект изображения. Затем он превращается в фотоизображение, как и раньше, и этикетка настраивается для его отображения. Последняя строка снова посвящена предотвращению сбора мусора.

Комментарии:

1. Для повернутого изображения лучше использовать другую переменную. На моем компьютере поворот изображения на 360 градусов на 1 градус добавляет артефакты.

2. Эта проблема, похоже, не возникает при поворотах на 90 градусов, также (я предполагаю), что пользователь хочет повернуть на 180 градусов, когда он дважды нажимает одну из кнопок, так что это самый простой способ ее реализации. В противном случае мне пришлось бы иметь другую переменную, чтобы отслеживать текущий угол.

3. Попробуйте, но я оставлю свой комментарий там для всех, кто найдет это в будущем. У них могут быть разные требования.

4. Спасибо! Это работает! Но это всегда изменяет размер изображений, могу ли я использовать это resized_image= image_loaded.resize((300,205), Изображение. ANTIALIAS) new_image= Изображение. Фотоизображение(измененное изображение) перед тем, как сделать image_loaded_label.image = загруженное изображение?

5. Это должно сработать, вы также можете попробовать добавить expand = True image_object.rotate(angle) .