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.Pathque sabe fazer uma porção de coisas úteis.
- Sabe listar os itens nele contidos, se for uma pasta com
p.iterdir(), entregando objetospathlib.Pathpara 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 imagemIsso 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