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

🎯 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
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.
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.
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.
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.
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.
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.
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.
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.
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

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.



