### Sesc Av. Paulista
## Grupo de estudos em Python
# `hackmd.io/@sesc-av-paulista/estudos-em-python-5-junho`
# Glith: a estética dos erros
> 
> https://en.wikipedia.org/wiki/Glitch_art
Será que dá para fazer uma ponte com as pequenas imperfeições da filosofia japonesa do Wabi-sabi?
Busque imagens: https://www.google.com/search?q=wabi+sabi
Palpite: valorização das imperfeições.
Como funciona o JPG por dentro?
https://www.lcs.poli.usp.br/~gstolfi/PPT/APTV0616.pdf
## Vamos estragar um arquivo JPG!
Original

Primeiro exemplo

```python=
from pathlib import Path
from random import randint
import io
from PIL import Image
# print(list(Path.cwd().iterdir()))
with open('piscina.jpg', 'rb') as f:
lista_bytes = list(f.read())
comprimento = len(lista_bytes)
pos = randint(0, comprimento)
novo_byte = randint(1, 255)
lista_bytes[pos] = novo_byte
stream = io.BytesIO(bytes(lista_bytes))
nova_imagem = Image.open(stream)
```
Com iterações
```python=
from pathlib import Path
from random import randint
import io
from PIL import Image
# print(list(Path.cwd().iterdir()))
with open('piscina.jpg', 'rb') as f:
lista_bytes = list(f.read())
comprimento = len(lista_bytes)
for i in range(50):
pos = randint(0, comprimento)
novo_byte = randint(1, 255)
lista_bytes[pos] = novo_byte
stream = io.BytesIO(bytes(lista_bytes))
nova_imagem = Image.open(stream)
nova_imagem.save(f'estragada{i}.jpg')
```
Depois de 48 bytes alterados por sorteio

Exemplo interativo com py5
```python=
from pathlib import Path
from random import randint
import io
from PIL import Image
# print(list(Path.cwd().iterdir()))
def setup():
global lista_bytes
size(800, 400)
with open('piscina.jpg', 'rb') as f:
lista_bytes = list(f.read())
no_loop()
def draw():
global py5image
comprimento = len(lista_bytes)
for _ in range(2):
pos = randint(0, comprimento)
novo_byte = randint(1, 255)
lista_bytes[pos] = novo_byte
stream = io.BytesIO(bytes(lista_bytes))
try:
nova_imagem = Image.open(stream)
py5image = convert_image(nova_imagem)
image(py5image, 0, 0)
except OSError as e:
print(e)
def key_pressed():
if key == ' ':
redraw()
if key == 's':
py5image.save(f'{frame_count}.jpg')
```


### Versão com seleção de imagens
```python!
from pathlib import Path
from random import randint
import io
from PIL import Image
caminho_imagem = Path('piscina.jpg')
def setup():
global py5image # para poder salvar!
size(800, 600)
#window_resizable(True) # acho que está com problema se usado com no_loop()!
#frame_rate(1)
no_loop()
carregando_bytes_imagem(caminho_imagem)
def carregando_bytes_imagem(imagem):
global lista_bytes
with open(imagem, 'rb') as f:
lista_bytes = list(f.read())
def draw():
global py5image
background(0)
comprimento = len(lista_bytes)
bytes_anteriores = lista_bytes.copy()
for _ in range(2):
pos = randint(0, comprimento)
novo_byte = randint(1, 255)
lista_bytes[pos] = novo_byte
stream = io.BytesIO(bytes(lista_bytes))
try:
nova_imagem = Image.open(stream)
py5image = convert_image(nova_imagem)
mostra(nova_imagem) # image parece que aceita imagens PIL!
except OSError as e:
lista_bytes[:] = bytes_anteriores
print(e)
def mostra(imagem):
ar = imagem.height / imagem.width
nova_largura = height / ar
if nova_largura > width:
image(imagem, 0, 0, width, height * ar)
else:
image(imagem, 0, 0, nova_largura, height)
def arquivo_selecionado(selection):
global caminho_imagem
if selection is None:
println("Não foi selecionado nenhum arquivo.")
else:
(f'Selecionado o arquivo: {selection}')
caminho_imagem = selection
carregando_bytes_imagem(caminho_imagem)
redraw()
def key_pressed():
if key == ' ':
redraw()
if key == 's':
nome = f'{caminho_imagem.stem}-glitch{frame_count}.jpg'
py5image.save(nome)
print(f'salvando {nome}')
if key == 'r':
carregando_bytes_imagem(caminho_imagem)
redraw()
if key == 'i':
select_input("Selecione uma imagem:", arquivo_selecionado)
```