Laboratório de Programação — Ciência da Computação
Conceitos de imagem digital e operações com Pillow — com syntax highlighting
(x, y) e intensidade/cor por pixel.Baseado no material “Manipulando Imagens com o Python”.
pip install Pillow
from PIL import Image
img = Image.open("foto.jpg") # abre
img.show() # exibe (visualizador do SO)
print(img.size, img.mode, img.format)
# Conversões simples
img_png = img.convert("RGBA")
img_png.save("saida.png") # mantém alfa
img_jpg = img.convert("RGB")
img_jpg.save("saida.jpg", quality=90, optimize=True)
from PIL import Image
img = Image.open("input.jpg")
# Redimensionar
thumb = img.resize((128, 128)) # tamanho fixo
thumb.save("thumb.jpg")
# Cortar (crop): caixa (esq, topo, dir, base)
crop = img.crop((100, 100, 400, 400))
crop.save("recorte.jpg")
# Rotacionar
rot = img.rotate(45, expand=True)
rot.save("rotacao_45.png")
# JPEG com qualidade
img.save("foto_q80.jpg", quality=80, subsampling=1)
# Modo de cor
print(img.mode) # "RGB", "RGBA", "L" (grayscale)...
g = img.convert("L") # escala de cinza
g.save("cinza.png")
# Metadados (EXIF) se disponíveis
exif = img.getexif()
print(dict(exif))
Exemplo inspirado no seu notebook/Colab.
from PIL import Image
# Abrir duas imagens
img1 = Image.open("my_bike.jpeg")
img2 = Image.open("my_bike2.jpeg")
# Definir largura combinada
largura_combinada = img1.width + img2.width
altura = max(img1.height, img2.height)
# Criar nova imagem (fundo branco)
img_comb = Image.new("RGB", (largura_combinada, altura), color=(255,255,255))
img_comb.paste(img1, (0, 0))
img_comb.paste(img2, (img1.width, 0))
img_comb.save("imagem_combinada.jpg")
img_comb.show()
from PIL import Image, ImageDraw, ImageFont
img = Image.open("my_bike2.jpeg").convert("RGB")
draw = ImageDraw.Draw(img)
# Fonte (padrão ou .ttf)
# fonte = ImageFont.truetype("arial.ttf", 24)
fonte = ImageFont.load_default()
# Texto
draw.text((10, 10), "Estilo Pablo Picasso", font=fonte, fill=(255,255,255))
# Borda (retângulo)
esp = 5
draw.rectangle([(0, 0), (img.width-1, img.height-1)],
outline=(0,0,0), width=esp)
img.save("imagem_modificada.jpg")
img.show()
ImageFont.truetype para controle de tipo/tamanho.stroke_width/stroke_fill (versões recentes) para contorno do texto.textbbox para alinhar.A imagem do logo deve ter fundo transparente (canal alfa) para melhor fusão.
from PIL import Image
# Base e logo com RGBA (alfa)
img = Image.open("Software Engineer.jpeg").convert("RGBA")
logo = Image.open("my_logo.png").convert("RGBA")
# Redimensionar logo até 25% da imagem
lw, lh = logo.size
max_w, max_h = int(img.width*0.25), int(img.height*0.25)
escala = min(max_w/lw, max_h/lh)
logo_rs = logo.resize((int(lw*escala), int(lh*escala)))
# Posição (canto inferior direito, margem 10px)
pos = (img.width - logo_rs.width - 10, img.height - logo_rs.height - 10)
# Compor preservando alfa do logo
img.paste(logo_rs, pos, mask=logo_rs)
# Salvar (PNG preserva transparência)
img.save("imagem_com_marca_dagua.png")
from PIL import Image
img = Image.open("my_bike.jpeg")
tamanho = (128, 128)
# resize: força o tamanho exato
thumb = img.resize(tamanho)
thumb.save("thumbnail.jpg")
# alternativa: thumbnail mantém proporção e "encaixa"
img2 = Image.open("my_bike.jpeg")
img2.thumbnail(tamanho) # altera in-place
img2.save("thumbnail_proporcional.jpg")
resize: quando você precisa de dimensões exatas (pode distorcer).thumbnail: quando precisa preservar a proporção original.thumbnail + crop central.from PIL import Image, ImageFilter, ImageEnhance
img = Image.open("foto.jpg")
# Filtros
blur = img.filter(ImageFilter.GaussianBlur(2))
edges = img.filter(ImageFilter.FIND_EDGES)
sharp = ImageEnhance.Sharpness(img).enhance(1.5)
bright = ImageEnhance.Brightness(img).enhance(1.2)
contr = ImageEnhance.Contrast(img).enhance(1.2)
blur.save("blur.jpg"); edges.save("edges.jpg")
sharp.save("sharp.jpg")
from PIL import Image, ImageDraw
img = Image.open("fundo.png").convert("RGBA")
draw = ImageDraw.Draw(img)
# Linha, retângulo e círculo
draw.line((10, 10, 200, 50), fill=(255,0,0,255), width=4)
draw.rectangle((20, 70, 220, 170), outline=(0,0,255,255), width=3)
draw.ellipse((250, 40, 340, 130), outline=(0,128,0,255), width=3)
img.save("formas.png")
from PIL import Image, ImageDraw, ImageFont
def combinar_lado_a_lado(a: str, b: str, out: str):
A, B = Image.open(a), Image.open(b)
w, h = A.width + B.width, max(A.height, B.height)
dest = Image.new("RGB", (w, h), (255,255,255))
dest.paste(A, (0, 0)); dest.paste(B, (A.width, 0))
dest.save(out); return out
def marca_dagua(base: str, logo: str, out: str, escala=0.25, margem=10):
img = Image.open(base).convert("RGBA")
log = Image.open(logo).convert("RGBA")
lw, lh = log.size
max_w, max_h = int(img.width*escala), int(img.height*escala)
s = min(max_w/lw, max_h/lh)
log = log.resize((int(lw*s), int(lh*s)))
pos = (img.width - log.width - margem, img.height - log.height - margem)
img.paste(log, pos, mask=log)
img.save(out); return out
Transforme seus passos em funções reutilizáveis para automação e clareza.
quality, optimize).