Visualizador de Imagens Usando Python e Tkinter

PythonBeginner
Pratique Agora

Introdução

Neste projeto, criaremos uma aplicação de visualização de imagens usando Python e Tkinter. O visualizador de imagens permitirá que você abra um arquivo de imagem, o exiba e execute ações como zoom in (aproximar), zoom out (afastar) e rotação da imagem. Usaremos a biblioteca PIL (Python Imaging Library) para lidar com operações de imagem e Tkinter para criar a interface gráfica do usuário.

👀 Pré-visualização

Pré-visualização da aplicação de visualização de imagens

🎯 Tarefas

Neste projeto, você aprenderá:

  • Como criar uma aplicação GUI (Graphical User Interface - Interface Gráfica do Usuário) usando Tkinter.
  • Como lidar com o carregamento e exibição de imagens usando PIL.
  • Como implementar a funcionalidade de zoom in, zoom out e rotação para a imagem exibida.

🏆 Conquistas

Após concluir este projeto, você será capaz de:

  • Desenvolver uma aplicação de visualização de imagens funcional usando Python e Tkinter.
  • Integrar capacidades de processamento de imagem usando a biblioteca PIL.
  • Implementar recursos básicos de manipulação de imagem, como zoom e rotação.

Criar os arquivos do projeto

Primeiramente, crie um novo arquivo chamado ~/project/image_viewer.py e abra-o em um editor de texto ou em um ambiente de desenvolvimento integrado (IDE - Integrated Development Environment).

cd ~/project
touch image_viewer.py
✨ Verificar Solução e Praticar

Importar as bibliotecas necessárias

No arquivo image_viewer.py, importe as bibliotecas necessárias:

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import os

A biblioteca tkinter fornece a funcionalidade para criar elementos da GUI, filedialog nos permite abrir uma caixa de diálogo para selecionar um arquivo de imagem, messagebox é usado para exibir mensagens ao usuário, PIL é usado para processamento de imagem e os fornece funções para interagir com o sistema operacional.

✨ Verificar Solução e Praticar

Criar a classe ImageViewer

Defina uma nova classe chamada ImageViewer que irá lidar com a aplicação de visualização de imagens:

class ImageViewer:
    def __init__(self, root):
        self.root = root
        self.root.title('LabEx Image Viewer')
        self.root.geometry('800x600')
        self.root.configure(background='white')

        self.image_label = tk.Label(self.root)
        self.image_label.pack()

        self.control_frame = tk.Frame(self.root)
        self.control_frame.pack()

        self.open_button = tk.Button(self.control_frame, text='Open', command=self.open_image)
        self.open_button.pack(side='left')

        self.close_button = tk.Button(self.control_frame, text='Quit', command=self.root.quit)
        self.close_button.pack(side='left')

        self.zoom_in_button = tk.Button(self.control_frame, text='Zoom In', command=self.zoom_in)
        self.zoom_in_button.pack(side='left')

        self.zoom_out_button = tk.Button(self.control_frame, text='Zoom Out', command=self.zoom_out)
        self.zoom_out_button.pack(side='left')

        self.rotate_button = tk.Button(self.control_frame, text='Rotate', command=self.rotate)
        self.rotate_button.pack(side='left')

        self.current_image_path = ''
        self.zoom_level = 1

No método __init__, inicializamos a janela raiz com um título, tamanho e cor de fundo. Em seguida, criamos um rótulo para exibir a imagem e um frame para conter os botões de controle (Open, Quit, Zoom In, Zoom Out, Rotate). Também definimos variáveis de instância para acompanhar o caminho da imagem atual e o nível de zoom.

✨ Verificar Solução e Praticar

Implementar o método open_image

Adicione o método open_image à classe ImageViewer:

    def open_image(self):
        self.current_image_path = filedialog.askopenfilename(defaultextension=".jpg",
            filetypes=[("All Files", "*.*"), ("JPEG", ".jpg"), ("PNG", ".png"), ("GIF", ".gif")])
        if self.current_image_path:
            self.load_image()

O método open_image abre uma caixa de diálogo de arquivo para selecionar um arquivo de imagem. Ele define a variável current_image_path para o caminho do arquivo selecionado e chama o método load_image para exibir a imagem.

✨ Verificar Solução e Praticar

Implementar o método load_image

Implemente o método load_image:

    def load_image(self):
        image = Image.open(self.current_image_path)

        ## Resize image for display
        max_size = (600, 600)
        image.thumbnail(max_size)

        ## Save a reference to the original image (for zooming/rotating)
        self.original_image = image

        ## Create a Tkinter-compatible image
        self.tk_image = ImageTk.PhotoImage(image)
        self.image_label.configure(image=self.tk_image)

        self.zoom_level = 1

O método load_image abre o arquivo de imagem selecionado usando o método Image.open do PIL. Ele redimensiona a imagem para caber dentro de um tamanho máximo de 600x600 pixels usando o método thumbnail. Em seguida, ele salva uma referência à imagem original para fins de zoom e rotação. Em seguida, ele cria uma imagem compatível com Tkinter usando ImageTk.PhotoImage e atualiza o rótulo da imagem para exibir a imagem carregada. Finalmente, ele define o nível de zoom inicial para 1.

✨ Verificar Solução e Praticar

Implementar o método zoom_in

Implemente o método zoom_in:

    def zoom_in(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.zoom_level *= 1.1  ## Increase zoom level by 10%
        self.zoom_or_rotate_image()

O método zoom_in verifica se uma imagem está carregada. Se nenhuma imagem estiver carregada, ele retorna. Caso contrário, ele aumenta o nível de zoom em 10% e chama o método zoom_or_rotate_image para atualizar a imagem exibida.

✨ Verificar Solução e Praticar

Implementar o método zoom_out

Implemente o método zoom_out:

    def zoom_out(self):
        if not self.current_image_path:  ## No image loaded
            return
        if self.zoom_level < 0.1:  ## Limit outwards zoom
            return
        self.zoom_level *= 0.9  ## Decrease zoom level by 10%
        self.zoom_or_rotate_image()

O método zoom_out verifica se uma imagem está carregada. Se nenhuma imagem estiver carregada, ele retorna. Se o nível de zoom já estiver abaixo de 0.1, o que significa que a imagem está com zoom out no limite, ele retorna. Caso contrário, ele diminui o nível de zoom em 10% e chama o método zoom_or_rotate_image para atualizar a imagem exibida.

✨ Verificar Solução e Praticar

Implementar o método rotate

Implemente o método rotate:

    def rotate(self):
        if not self.current_image_path:  ## No image loaded
            return
        self.original_image = self.original_image.rotate(-90)
        self.zoom_or_rotate_image()

O método rotate verifica se uma imagem está carregada. Se nenhuma imagem estiver carregada, ele retorna. Caso contrário, ele rotaciona a imagem original em -90 graus usando o método rotate da PIL e chama o método zoom_or_rotate_image para atualizar a imagem exibida.

✨ Verificar Solução e Praticar

Implementar o método zoom_or_rotate_image

Implemente o método zoom_or_rotate_image:

    def zoom_or_rotate_image(self):
        ## Zoom and rotate original image, convert to Tk image, and display
        new_image = self.original_image.resize((int(self.original_image.width * self.zoom_level),
                                                int(self.original_image.height * self.zoom_level)))
        self.tk_image = ImageTk.PhotoImage(new_image)
        self.image_label.configure(image=self.tk_image)

O método zoom_or_rotate_image redimensiona a imagem original com base no nível de zoom atual. Ele cria uma nova imagem com o tamanho atualizado usando o método resize da PIL. Em seguida, ele converte a nova imagem para uma imagem compatível com Tkinter usando ImageTk.PhotoImage e atualiza o rótulo da imagem para exibir a imagem atualizada.

✨ Verificar Solução e Praticar

Criar o loop principal da aplicação

Adicione o seguinte código no final do arquivo image_viewer.py para criar o loop principal da aplicação:

if __name__ == '__main__':
    root = tk.Tk()
    app = ImageViewer(root)
    root.mainloop()

Este código cria uma janela raiz Tkinter, inicializa uma instância da classe ImageViewer e inicia o loop principal da aplicação.

Mude para a Área de Trabalho e execute o arquivo image_viewer.py para testar a aplicação. Você deve ver a seguinte janela:

python image_viewer.py
Janela da aplicação Tkinter
✨ Verificar Solução e Praticar

Resumo

Parabéns! Você criou uma aplicação de visualização de imagens usando Python e Tkinter. A aplicação permite que você abra um arquivo de imagem, exiba-o e execute ações como aumentar o zoom, diminuir o zoom e rotacionar a imagem. Você aprendeu como usar a biblioteca PIL para processamento de imagens e Tkinter para criar a interface gráfica do usuário. Sinta-se à vontade para personalizar a aplicação ainda mais ou explorar funcionalidades adicionais.