im = Image.open("grayscale.bmp")
data = im.load()
data[1,1] = 1
报告“ValueError:image is readonly”。只有8位灰度级bmp图像才会引发此异常。为什么? 顺便说一句,我无法从8位灰度bmp图像中获取调色板。但根据BMP规范,存在调色板。为什么呢?
答案 0 :(得分:3)
让我们从第二个问题开始。基本上,当使用调色板加载BMP文件时,PIL会检查该调色板是否包含至少一个rgb三元组,其中值并非全部相等。如果所有三元组都相等,那么它将采用灰度图像并且从不创建调色板,因此im.palette
在这种情况下始终为空。
对于第一个问题,你可能不想知道“为什么”,但我想如何解决它。否则,您获得只读图像的简化原因是由于PIL的内部细节:灰度级bmp是内存映射的,而PIL仅支持只读模式(这似乎专门用于处理Windows问题)。解决这个问题的“修复”很简单,但不是很完美:将图像转换为某种模式,现在它不再是只读的。您甚至可以转换为'L'(这是您的当前模式)。
我不记得有这个问题,因为当我必须处理PIL中的图像时,我通常需要它们在某种特定模式下,所以我总是做img.convert(X)
,其中X
是我需要的模式。
答案 1 :(得分:0)
我对ValueError: image is readonly
和8位灰度bmp有同样的问题。似乎仍然可以通过image.putpixel((x, y), value)
更改单个像素值,尽管它比直接在像素图上操作要慢。