Processamento de Imagens com Python
Aprenda processamento de imagens com Python e Pillow. Redimensione, aplique filtros, adicione textos e automatize manipulacoes em lote.
Processamento de imagens e uma habilidade valiosa para desenvolvedores Python. Desde redimensionar fotos para um site ate criar thumbnails em lote ou aplicar marcas dagua, a biblioteca Pillow oferece tudo o que voce precisa. Neste artigo, vamos explorar as operacoes mais uteis com exemplos praticos e prontos para usar.
Instalacao e Conceitos Basicos
Instale o Pillow, o fork mantido da classica PIL (Python Imaging Library):
pip install Pillow
O Pillow trabalha com o conceito de objetos Image. Cada imagem tem modo (RGB, RGBA, L para escala de cinza), tamanho e pixels:
from PIL import Image
# Abrir uma imagem
img = Image.open("foto.jpg")
# Informacoes basicas
print(f"Formato: {img.format}")
print(f"Tamanho: {img.size}") # (largura, altura)
print(f"Modo: {img.mode}") # RGB, RGBA, L, etc.
print(f"Resolucao: {img.info.get('dpi', 'N/A')}")
# Mostrar a imagem (abre no visualizador padrao)
img.show()
Redimensionamento e Recorte
As operacoes mais comuns envolvem alterar o tamanho das imagens:
from PIL import Image
def redimensionar(caminho: str, largura: int, altura: int, saida: str):
"""Redimensiona mantendo ou nao a proporcao."""
img = Image.open(caminho)
img_redimensionada = img.resize((largura, altura), Image.Resampling.LANCZOS)
img_redimensionada.save(saida)
print(f"Redimensionada: {img.size} -> {img_redimensionada.size}")
def thumbnail(caminho: str, tamanho_max: tuple, saida: str):
"""Cria thumbnail mantendo proporcao."""
img = Image.open(caminho)
img.thumbnail(tamanho_max, Image.Resampling.LANCZOS)
img.save(saida)
print(f"Thumbnail criado: {img.size}")
def recortar(caminho: str, caixa: tuple, saida: str):
"""Recorta uma regiao da imagem (esquerda, cima, direita, baixo)."""
img = Image.open(caminho)
img_recortada = img.crop(caixa)
img_recortada.save(saida)
print(f"Recortada: {img_recortada.size}")
# Exemplos de uso
redimensionar("foto.jpg", 800, 600, "foto_800x600.jpg")
thumbnail("foto.jpg", (300, 300), "foto_thumb.jpg")
recortar("foto.jpg", (100, 100, 500, 400), "foto_recortada.jpg")
Aplicando Filtros e Efeitos
O Pillow oferece diversos filtros prontos e permite criar efeitos personalizados:
from PIL import Image, ImageFilter, ImageEnhance
def aplicar_filtros(caminho: str):
"""Demonstra varios filtros disponiveis."""
img = Image.open(caminho)
# Filtros prontos
desfocada = img.filter(ImageFilter.GaussianBlur(radius=5))
desfocada.save("desfocada.jpg")
nitida = img.filter(ImageFilter.SHARPEN)
nitida.save("nitida.jpg")
bordas = img.filter(ImageFilter.FIND_EDGES)
bordas.save("bordas.jpg")
relevo = img.filter(ImageFilter.EMBOSS)
relevo.save("relevo.jpg")
contorno = img.filter(ImageFilter.CONTOUR)
contorno.save("contorno.jpg")
def ajustar_imagem(caminho: str):
"""Ajusta brilho, contraste e saturacao."""
img = Image.open(caminho)
# Aumentar brilho em 30%
brilho = ImageEnhance.Brightness(img)
img_brilho = brilho.enhance(1.3)
img_brilho.save("brilho_aumentado.jpg")
# Aumentar contraste em 50%
contraste = ImageEnhance.Contrast(img)
img_contraste = contraste.enhance(1.5)
img_contraste.save("contraste_aumentado.jpg")
# Saturacao
saturacao = ImageEnhance.Color(img)
img_saturada = saturacao.enhance(1.4)
img_saturada.save("saturada.jpg")
# Preto e branco
img_pb = img.convert("L")
img_pb.save("preto_branco.jpg")
aplicar_filtros("foto.jpg")
ajustar_imagem("foto.jpg")
Marca Dagua e Texto
Adicionar textos e marcas dagua e essencial para proteger imagens:
from PIL import Image, ImageDraw, ImageFont
def adicionar_marca_dagua(caminho: str, texto: str, saida: str):
"""Adiciona marca dagua de texto a imagem."""
img = Image.open(caminho).convert("RGBA")
largura, altura = img.size
# Criar camada transparente
overlay = Image.new("RGBA", img.size, (255, 255, 255, 0))
draw = ImageDraw.Draw(overlay)
# Fonte (use uma fonte do sistema ou baixe uma)
try:
fonte = ImageFont.truetype("arial.ttf", 40)
except OSError:
fonte = ImageFont.load_default()
# Calcular posicao centralizada
bbox = draw.textbbox((0, 0), texto, font=fonte)
texto_largura = bbox[2] - bbox[0]
texto_altura = bbox[3] - bbox[1]
x = (largura - texto_largura) // 2
y = (altura - texto_altura) // 2
# Desenhar texto semi-transparente
draw.text((x, y), texto, font=fonte, fill=(255, 255, 255, 100))
# Combinar camadas
resultado = Image.alpha_composite(img, overlay)
resultado.convert("RGB").save(saida)
print(f"Marca dagua adicionada: {saida}")
def adicionar_texto(caminho: str, texto: str, posicao: tuple, saida: str):
"""Adiciona texto simples a imagem."""
img = Image.open(caminho)
draw = ImageDraw.Draw(img)
try:
fonte = ImageFont.truetype("arial.ttf", 30)
except OSError:
fonte = ImageFont.load_default()
# Sombra do texto
draw.text((posicao[0] + 2, posicao[1] + 2), texto, font=fonte, fill="black")
# Texto principal
draw.text(posicao, texto, font=fonte, fill="white")
img.save(saida)
adicionar_marca_dagua("foto.jpg", "Python Brasil", "foto_marca.jpg")
adicionar_texto("foto.jpg", "Julho 2025", (20, 20), "foto_texto.jpg")
Processamento em Lote
A automacao brilha quando voce precisa processar centenas de imagens:
import os
from pathlib import Path
from PIL import Image
def processar_lote(
pasta_entrada: str,
pasta_saida: str,
largura_max: int = 1200,
qualidade: int = 85,
):
"""Processa todas as imagens de uma pasta."""
pasta_saida_path = Path(pasta_saida)
pasta_saida_path.mkdir(parents=True, exist_ok=True)
extensoes = {".jpg", ".jpeg", ".png", ".webp", ".bmp"}
processadas = 0
erros = 0
for arquivo in Path(pasta_entrada).iterdir():
if arquivo.suffix.lower() not in extensoes:
continue
try:
img = Image.open(arquivo)
# Redimensionar se necessario
if img.width > largura_max:
proporcao = largura_max / img.width
nova_altura = int(img.height * proporcao)
img = img.resize(
(largura_max, nova_altura), Image.Resampling.LANCZOS
)
# Converter RGBA para RGB (necessario para JPEG)
if img.mode == "RGBA":
fundo = Image.new("RGB", img.size, (255, 255, 255))
fundo.paste(img, mask=img.split()[3])
img = fundo
# Salvar otimizada
saida = pasta_saida_path / f"{arquivo.stem}.jpg"
img.save(saida, "JPEG", quality=qualidade, optimize=True)
processadas += 1
tamanho_original = arquivo.stat().st_size / 1024
tamanho_novo = saida.stat().st_size / 1024
economia = (1 - tamanho_novo / tamanho_original) * 100
print(f" {arquivo.name}: {tamanho_original:.0f}KB -> {tamanho_novo:.0f}KB ({economia:.0f}% menor)")
except Exception as e:
print(f" Erro em {arquivo.name}: {e}")
erros += 1
print(f"\nProcessadas: {processadas} | Erros: {erros}")
processar_lote("fotos_originais/", "fotos_otimizadas/", largura_max=1200)
Criando Colagens e Composicoes
Combine multiplas imagens em uma unica composicao:
from PIL import Image
def criar_colagem(caminhos: list[str], colunas: int, saida: str):
"""Cria uma colagem com as imagens fornecidas."""
tamanho_celula = (300, 300)
imagens = []
for caminho in caminhos:
img = Image.open(caminho)
img.thumbnail(tamanho_celula, Image.Resampling.LANCZOS)
imagens.append(img)
linhas = (len(imagens) + colunas - 1) // colunas
largura_total = colunas * tamanho_celula[0]
altura_total = linhas * tamanho_celula[1]
colagem = Image.new("RGB", (largura_total, altura_total), (255, 255, 255))
for i, img in enumerate(imagens):
col = i % colunas
lin = i // colunas
x = col * tamanho_celula[0] + (tamanho_celula[0] - img.width) // 2
y = lin * tamanho_celula[1] + (tamanho_celula[1] - img.height) // 2
colagem.paste(img, (x, y))
colagem.save(saida)
print(f"Colagem criada: {largura_total}x{altura_total}")
fotos = ["foto1.jpg", "foto2.jpg", "foto3.jpg", "foto4.jpg", "foto5.jpg", "foto6.jpg"]
criar_colagem(fotos, colunas=3, saida="colagem.jpg")
Boas Praticas
Sempre trabalhe com copias das imagens originais para evitar perda de dados. Use o formato JPEG para fotos e PNG para imagens com transparencia. Ao salvar JPEGs, ajuste a qualidade entre 80 e 90 para um bom equilibrio entre tamanho e qualidade visual. Para processamento em lote, trate excecoes individualmente para que um erro em uma imagem nao interrompa todo o processo. E libere memoria explicitamente com img.close() ao processar muitas imagens.
Conclusao
O Pillow e uma biblioteca completa e acessivel para processamento de imagens em Python. Desde operacoes simples como redimensionamento ate composicoes complexas com filtros e marcas dagua, ele cobre praticamente todas as necessidades. Combine-o com automacao em lote e voce tera uma ferramenta indispensavel no seu kit de desenvolvimento.
Equipe Python Brasil
Contribuidor do Python Brasil — Aprenda Python em Português