# Ateliê aberto: desenho com programação ## 26 de fevereiro – Recortes e Colagens digitais ## `hackmd.io/@sesc-av-paulista/desenho-com-prog-2026-03-05` ### Ferramentas que vamos usar: - Thonny + py5: https://abav.lugaralgum.com/como-instalar-py5/ - Editor online: https://abav.lugaralgum.com/pyp5js/py5mode/ - Material de apoio sobre recorte de imagens: https://abav.lugaralgum.com/material-aulas/Processing-Python-py5/recortando_imagens.html Assuntos: - Carregar imagens na memória - Copiar regiões da imagem (retangulares) - Máscaras de recorte - Bordas suaves - Como recortar uma imagem maior com uma máscara menor Extras: - Visão Computacional (OpenCV) https://docs.opencv.org/4.x/index.html - https://github.com/villares/sketch-a-day/blob/main/2025/sketch_2025_08_08/sketch_2025_08_08.py Conversas paralelas: - Chess OCR https://helpman.komtera.lt/chessocr/ - https://github.com/npcardoso/chessocr - https://www.kaggle.com/code/kevinl120/chess-ocr-e2e https://en.wikipedia.org/wiki/Euphorbia_griffithii ![image](https://hackmd.io/_uploads/ry2rUrwK-g.png) ![plantaB](https://hackmd.io/_uploads/ByY2BHvt-x.jpg) ### Carregando a imagem ```python= import py5 def setup(): global img py5.size(800, 800) img = py5.load_image('planta.jpg') def draw(): py5.image(img, 0, 0, 800, 800) py5.run_sketch(block=False) # não funciona no MacOS ``` ### `.get_pixels(x, y, w, h)` É diferente de `get_pixels(x, y)` que devolve a cor de um só pixel... devolve um Py5Image ![image](https://hackmd.io/_uploads/Hy0QMLDY-x.png) ### `.copy()` ```python= import py5 def setup(): global img, imgB py5.size(800, 800) img = py5.load_image('planta.jpg') imgB = py5.load_image('plantaB.jpg') def draw(): py5.image(img, 0, 0, 800, 800) img.copy(imgB, 150, 150, 200, 200, 100, 100, 2000, 2000) py5.run_sketch(block=False) # não funciona no MacOS ``` ### Máscaras ![image](https://hackmd.io/_uploads/HJD83SwYZx.png) `mask() can only be used with an image that's the same size.` A máscara: ![image](https://hackmd.io/_uploads/rkwSpHDtWx.png) ```python= import py5 def setup(): global img, imgB, mascara py5.size(800, 800) py5.background(0) imgB = py5.load_image('plantaB.jpg') mascara = py5.create_graphics(imgB.width, imgB.height) mascara.begin_draw() mascara.fill(255) mascara.circle(400, 400, 660) mascara.fill(80) mascara.rect(0, 600, 800, 100) mascara.end_draw() #py5.image(mascara, 0, 0) imgB.mask(mascara) py5.image(imgB, 0, 0) py5.run_sketch(block=False) # não funciona no MacOS ``` #### Borda suave ![image](https://hackmd.io/_uploads/rkXy18DYbg.png) ![image](https://hackmd.io/_uploads/ByqbkUDFWl.png) ```python= import py5 def setup(): global img, imgB, mascara py5.size(800, 800) py5.background(0) imgB = py5.load_image('plantaB.jpg') mascara = py5.create_graphics(imgB.width, imgB.height) mascara.begin_draw() mascara.no_stroke() for d in range(650, 650 - 255, -1): mascara.fill(py5.remap(d, 650, 650 - 255, 0, 255)) mascara.circle(400, 400, d) mascara.end_draw() #py5.image(mascara, 0, 0) imgB.mask(mascara) py5.image(imgB, 0, 0) py5.run_sketch(block=False) # não funciona no MacOS ``` #### Transição com blur no fundo ```python= import py5 def setup(): global img, imgB, mascara py5.size(800, 800) py5.background(0) imgB = py5.load_image('plantaB.jpg') py5.image(imgB, 0, 0) py5.apply_filter(py5.BLUR, 10) mascara = py5.create_graphics(imgB.width, imgB.height) mascara.begin_draw() mascara.no_stroke() for d in range(650, 650 - 255, -1): mascara.fill(py5.remap(d, 650, 650 - 255, 0, 255)) mascara.circle(400, 400, d) mascara.end_draw() #py5.image(mascara, 0, 0) imgB.mask(mascara) py5.image(imgB, 0, 0) py5.run_sketch(block=False) # não funciona no MacOS ``` ![image](https://hackmd.io/_uploads/rkIYlLwYWx.png) ### Recortes de regiões menores ```python= import py5 def setup(): global img, imgB, mascara py5.size(800, 800) py5.background(0) imgB = py5.load_image('plantaB.jpg') #py5.image(imgB, 0, 0) mascara = py5.create_graphics(400, 400) mascara.begin_draw() mascara.stroke(255) d = 6 mascara.stroke_weight(d) mascara.stroke_join(py5.ROUND) mascara.rect(d / 2, d / 2, 400 - d, 200 - d) mascara.triangle(100, 200, 200, 200, 300, 400 - d) mascara.end_draw() recorte = recorte_com_mascara(imgB, mascara, 100, 100) py5.image(recorte, 100, 100) #py5.image(mascara, 0, 0) def recorte_com_mascara(img, mascara, x, y): w, h = mascara.width, mascara.height resultado = py5.create_image(mascara.width, mascara.height, py5.ARGB) resultado.copy(img, int(x), int(y), w, h, 0, 0, w, h) resultado.mask(mascara) return resultado py5.run_sketch(block=False) # não funciona no MacOS ``` ![image](https://hackmd.io/_uploads/Ske3L8vFWe.png) ### Estudo final ```python= import py5 def setup(): global imgA, imgB, mascara py5.size(800, 800) py5.background(0) imgB = py5.load_image('plantaB.jpg') imgA = py5.load_image('planta.jpg') imgA.copy(imgA, 0, 0, imgA.width, imgA.height, 0, 0, 800, 800) mascara = py5.create_graphics(200, 200) mascara.begin_draw() mascara.stroke(255) d = 6 mascara.stroke_weight(d) mascara.stroke_join(py5.ROUND) mascara.rect(d / 2, d / 2, 200 - d, 100 - d) mascara.triangle(50, 100, 100, 100, 150, 200 - d) mascara.end_draw() py5.no_loop() def draw(): for x in range(50, 800, 250): for y in range(50, 800, 250): img = py5.random_choice((imgA, imgB)) xr = py5.random(0, img.width - 200) yr = py5.random(0, img.height - 200) recorte = recorte_com_mascara(img, mascara, xr, yr) py5.image(recorte, x, y) #py5.image(mascara, 0, 0) def recorte_com_mascara(img, mascara, x, y): w, h = mascara.width, mascara.height resultado = py5.create_image(mascara.width, mascara.height, py5.ARGB) resultado.copy(img, int(x), int(y), w, h, 0, 0, w, h) resultado.mask(mascara) return resultado def key_pressed(): if py5.key == ' ': py5.redraw() elif py5.key == 's': py5.save_frame('###.png') py5.run_sketch(block=False) # não funciona no MacOS ``` ![059](https://hackmd.io/_uploads/ByEpt8DYZx.png)