TLDR:我的目标很简单。我有一个 PNG 文件。我想使用 Python 在其中绘制一个矩形并将其保存到新文件中。
我有一个 PNG 文件(附在本帖中)。我只想使用 Python 在图像中绘制一个矩形,然后将图像保存到新文件中。以下代码不起作用:
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)
最后一行产生以下错误:
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)
现在,为了分解它,我尝试将图像对象复制到 Writer,而不进行任何更改:
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)
然后我收到此消息:
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
我完全搞不清楚哪里出了问题。有人能告诉我该怎么做吗?
您正在读取一个每像素 8 位的调色板图像。
Writer
除非您为其指定参数,否则对象不会使用该格式palette
。它试图写入每像素 24 位,因此一行远远不够。做出以下细微的改变:
我搞明白了。它有点笨拙,因为它会改变调色板中一种颜色的值。但是,它确实绘制了一个矩形,而这正是我真正需要的。