Lendo todas as imagens da pasta data
Exemplo de execução usando imagens medievais coletadas pelo artista e educador Daniel Seda.
Tendo visto previamente como ler e usar imagens de arquivos externos com load_image()
, e a estrutura de dados lista (list
) neste exemplo vamos carregar todas as imagens encontradas na pasta data
localizada dentro da pasta do seu sketch. Depois vamos “sortear”, uma imagem para mostrar usando a função random.choice
. A cada clique do mouse uma nova imagem será mostrada.
Para começar, é preciso criar uma variável global para guardar os dados das imagens carregados dos arquivos encontrados, fazemos isso com a linha imagens = []
antes do setup()
que cria uma lista vazia e aponta o nome imagens
para ela.
Usaremos a função sketch_path()
do py5, com o argumento 'data'
para obter o caminho da pasta data que está ao lado do seu sketch.
Note que essa informação obtida do caminho da pasta no disco (path) não é um simples string mas um objeto especial da biblioteca padrão do Python do tipo
pathlib.Path
que sabe fazer uma porção de coisas úteis.
- Sabe listar os itens nele contidos, se for uma pasta com
p.iterdir()
, entregando objetospathlib.Path
para cada um deles.- Sabe informar se é um arquivo (e não pasta/sub-pasta) com
p.is_file()
- Não vamos usar aqui, mas é possível juntar um nome de arquivo ou de uma sub-pasta com o path da pasta mãe, formando o “caminho completo” do item:
caminho_imagem = sketch_path('data') / 'uma_imagem.png' # um novo pathlib.Path que aponta para a imagem
Isso pode ser importante saber no futuro pois em diferentes sistemas operacionais os strings que representam o caminho para um arquivo ou pasta usam símbolos diferentes como separadores em cada sistema, melhor deixar o Python fazer a junção para você!
Depois do procedimento que popula a lista caminhos_arquivos
, que contém o caminho completo para os arquivos de imagem, nós vamos pegar cada um desses caminhos e usá-lo para carregar os dados da imagem com a função load_image()
do py5. Essa função aceita um string com a localização de um arquivo no disco, mas aceita também um objeto pathlib.Path
, e devolve um objeto Py5Image
que pode ser mostrado na tela com a função image()
posteriormente.
from random import choice
imagens = [] # Lista que vai receber objetos Py5Image (Processing Image data)
def setup():
size(400, 400)
# Path da pasta data, não use antes do setup!
data_folder = sketch_path('data') # este é um objeto pathlib.Path
# Ponha as imagens na pasta /data/ ao lado do seu sketch
# Começa olhando para os itens da pasta, confere se é uma imagem e
# se for, guarda na lista caminhos_arquivos.
caminhos_arquivos = []
# Repare que .iterdir() e .is_file() são métodos dos objetos pathlib.Path
# .iterdir() entrega Path dos seus itens, mas vai crashar se a pasta não existir
for caminho_arquivo in data_folder.iterdir():
if caminho_arquivo.is_file() and parece_ser_arquivo_de_imagem(caminho_arquivo):
caminhos_arquivos.append(caminho_arquivo)
# Agora efetivamente carrega na memória cada imagem a partir dos caminhos
# listados no passo anterior. Se alista estiver vazia não faz nada.
for caminho_arquivo in caminhos_arquivos:
img = load_image(caminho_arquivo)
imagens.append(img)
# Vamos congelar a repetição do draw() com no_loop().
no_loop()
# Clique com o mouse para uma nova imagem, redraw() na função mouse_clicked()
def draw():
background(0)
random_image = choice(imagens)
# Para encolher proporcionalmente a imagem caso ela não caiba na àrea de desenho
fator_escala = 1 # caso a imagem caiba perfeitamente
# se a largura da imagem for maior que a largura da àrea de desenho
if random_image.width > width:
fator_escala = width / random_image.width
# se mesmo tento sido já reduzida, a altura não couber
if random_image.height * fator_escala > height:
fator_escala = height / random_image.height
# Mostra a imagem centrada na àrea de desenho
image_mode(CENTER)
image(random_image, width / 2, height / 2,
random_image.width * fator_escala, random_image.height * fator_escala)
def mouse_clicked(): # executada quando o mouse é clicado
redraw() # pede para executar mais um ciclo da função draw()
def parece_ser_arquivo_de_imagem(file_path):
"""
Responde se a extensão do arquivo está entre as extensões válidas para imagens.
"""
extensoes_de_imagem = ('jpg', 'png', 'jpeg', 'gif', 'tif', 'tga')
extensao = file_path.suffix.lower()[1:] # sufixo convertido em minúsculas, a partir da segunda posição
# exemplo: Se file_path for Path('ARVORE.JPEG') o file_path.suffix será '.JPEG'
# file_path.suffix.lower() vai ser '.jpeg' e file_path.suffix.lower()[1:] e a extensao fica 'jpeg'
return extensao in extensoes_de_imagem
Uma versão que checa se a pasta existe e não dá erro se a pasta estiver vazia
clique para ver
from random import choice imagens = [] # Lista que vai receber objetos Py5Image (Processing Image data) def setup(): size(400, 400) data_folder = sketch_path('data') # este é um objeto pathlib.Path caminhos_arquivos = [] try: for caminho_arquivo in data_folder.iterdir(): if caminho_arquivo.is_file() and parece_ser_arquivo_de_imagem(caminho_arquivo): caminhos_arquivos.append(caminho_arquivo) except OSError as e: print(e) # Exemplo: [Errno 2] Arquivo ou diretório inexistente: '~/exemplos/data' # Agora efetivamente carrega na memória cada imagem a partir dos caminhos # listados no passo anterior. Se alista estiver vazia não faz nada. for caminho_arquivo in caminhos_arquivos: try: img = load_image(caminho_arquivo) imagens.append(img) except Exception as e: print(e) # Erro quando não foi possível carregar a imagem # Vamos congelar a repetição do draw() com no_loop(). no_loop() # Clique com o mouse para uma nova imagem, redraw() na função mouse_clicked() def draw(): background(0) if imagens: random_image = choice(imagens) else: random_image = create_graphics(400, 400) random_image.begin_draw() random_image.text_size(20) random_image.text('Imagens não encontradas', 100, 100) random_image.end_draw() # Para encolher proporcionalmente a imagem caso ela não caiba na àrea de desenho fator_escala = 1 # caso a imagem caiba perfeitamente # se a largura da imagem for maior que a largura da àrea de desenho if random_image.width > width: fator_escala = width / random_image.width # se mesmo tento sido já reduzida, a altura não couber if random_image.height * fator_escala > height: fator_escala = height / random_image.height # Mostra a imagem centrada na àrea de desenho image_mode(CENTER) image(random_image, width / 2, height / 2, random_image.width * fator_escala, random_image.height * fator_escala) def mouse_clicked(): # executada quando o mouse é clicado redraw() # pede para executar mais um ciclo da função draw() def parece_ser_arquivo_de_imagem(file_path): extensoes_de_imagem = ('jpg', 'png', 'jpeg', 'gif', 'tif', 'tga') extensao = file_path.suffix.lower()[1:] # sufixo convertido em minúsculas, a partir da segunda posição return extensao in extensoes_de_imagem
Assuntos relacionados
- Estrutura de pixels das imagens em Pixels e imagens
- Lendo e escrevendo texto em arquivos (file IO)
- Lendo todas as imagens de uma pasta selecionada pela pessoa usuária