简体   繁体   English

为什么PIL不能修改灰度BMP图像数据?

[英]Why can't PIL modify gray-scale BMP image data?

im = Image.open("grayscale.bmp")
data = im.load()
data[1,1] = 1

It reports "ValueError: image is readonly". 它报告“ValueError:image is readonly”。 Only 8-bit grayscale bmp image will raise this exception. 只有8位灰度级bmp图像才会引发此异常。 Why? 为什么? BTW, I cannot get the palette from 8-bit grayscale bmp image. 顺便说一句,我无法从8位灰度bmp图像中获取调色板。 But according to the BMP specification, there exists palette. 但根据BMP规范,存在调色板。 Why? 为什么?

Let's start with the second question. 让我们从第二个问题开始。 Basically, when loading a BMP file with palette, PIL checks whether that palette contains at least one rgb triple where the values are not all equal. 基本上,当使用调色板加载BMP文件时,PIL会检查该调色板是否包含至少一个rgb三元组,其中值并非全部相等。 If all triples are equal, then it assumes a grayscale image and the palette is never created, thus im.palette is always empty in this situation. 如果所有三元组都相等,那么它将采用灰度图像并且从不创建调色板,因此在这种情况下, im.palette始终为空。

For the first question you probably don't want to know "why", but how to fix it, I guess. 对于第一个问题,你可能不想知道“为什么”,但我想如何解决它。 Otherwise, the simplified reason you get a readonly image is due to internal details of PIL: a grayscale bmp is memory mapped and PIL only supports readonly mode for that (which seems to be done exclusively to handle Windows issues). 否则,您获得只读图像的简化原因是由于PIL的内部细节:灰度级bmp是内存映射的,而PIL仅支持只读模式(这似乎专门用于处理Windows问题)。 The "fix" for the problem is simple but not totally nice: convert the image to some mode and now it is no longer readonly. 解决这个问题的“修复”很简单,但不是很完美:将图像转换为某种模式,现在它不再是只读的。 You can even convert to 'L' (which is the current mode in your case). 您甚至可以转换为'L'(这是您的当前模式)。

I don't remember having a problem with this because when I have to deal with images in PIL, I usually need them in some specific mode, so I always do a img.convert(X) , where X is the mode I need. 我不记得有这个问题,因为当我必须处理PIL中的图像时,我通常需要它们在某种特定模式下,所以我总是做一个img.convert(X) ,其中X是我需要的模式。

I've got the same problem with ValueError: image is readonly and 8-bit grayscale bmp. 我对ValueError: image is readonly有同样的问题ValueError: image is readonly和8-bit灰度bmp。 It seems that it is still possible to change single pixel value via image.putpixel((x, y), value) though it's slower than manipulating directly on pixel map. 似乎仍然可以通过image.putpixel((x, y), value)更改单个像素值image.putpixel((x, y), value)尽管它比直接在像素图上操作要慢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM