TLDR: Meu objetivo é simples. Tenho um arquivo PNG. Quero desenhar um retângulo nele usando Python e salvá-lo em um novo arquivo.
Tenho um arquivo PNG (anexado a este post). Tudo o que quero fazer é desenhar um retângulo na imagem usando Python e salvar a imagem em um novo arquivo. Aqui está o código que não funciona:
import png
org_path = './arragon.png'
altered_path = './altered.png'
f = open(org_path, 'rb')
image = png.Reader(file=f)
width, height, rows, metadata = image.read()
for row in rows:
for i in range(len(row)):
row[i] = 255
writer = png.Writer(
width=width,
height=height,
bitdepth=metadata['bitdepth'],
greyscale=metadata['greyscale'],
alpha=metadata['alpha']
)
writer.write(open(altered_path, 'wb'), rows)
A última linha produz o seguinte erro:
Traceback (most recent call last):
File "/home/miko/tmp/alter-image/./edit.py", line 23, in <module>
writer.write(open(altered_path, 'wb'), rows)
File "/home/miko/.local/lib/python3.10/site-packages/png.py", line 670, in write
raise ProtocolError(
png.ProtocolError: ProtocolError: rows supplied (0) does not match height (450)
Agora, para simplificar, tentei apenas copiar o objeto de imagem para um Writer, sem nenhuma alteração:
import png
f = open(org_path, 'rb')
image = png.Reader(file=f)
width, height, rows, metadata = image.read()
writer = png.Writer(
width=width,
height=height,
bitdepth=metadata['bitdepth'],
greyscale=metadata['greyscale'],
alpha=metadata['alpha']
)
writer.write(open(altered_path, 'wb'), rows)
Então recebo esta mensagem:
Traceback (most recent call last):
File "/home/miko/tmp/alter-image/./edit.py", line 23, in <module>
writer.write(open(altered_path, 'wb'), rows)
File "/home/miko/.local/lib/python3.10/site-packages/png.py", line 668, in write
nrows = self.write_passes(outfile, check_rows(rows))
File "/home/miko/.local/lib/python3.10/site-packages/png.py", line 703, in write_passes
return self.write_packed(outfile, rows)
File "/home/miko/.local/lib/python3.10/site-packages/png.py", line 738, in write_packed
for i, row in enumerate(rows):
File "/home/miko/.local/lib/python3.10/site-packages/png.py", line 658, in check_rows
raise ProtocolError(
png.ProtocolError: ProtocolError: Expected 633 values but got 211 values, in row 0
Não consigo entender o que está errado. Alguém pode me dizer como fazer isso?
Você está lendo uma imagem paletizada que tem 8 bits por pixel. O
Writer
objeto não usa esse formato a menos que você dê umpalette
argumento a ele. Ele está tentando escrever 24 bits por pixel, então uma linha fica muito curta.Faça esta mudança sutil:
Eu descobri. É um pouco desajeitado porque muda o valor de uma das cores na paleta. No entanto, ele desenha um retângulo, que é tudo o que eu realmente preciso.