im = Image.open("grayscale.bmp")
data = im.load()
data[1,1] = 1
「ValueError: 画像は読み取り専用です」と報告されます。この例外が発生するのは、8 ビットのグレースケール bmp イメージのみです。なんで?ところで、8 ビット グレースケールの bmp イメージからパレットを取得できません。しかし、BMP 仕様によれば、パレットが存在します。なんで?
im = Image.open("grayscale.bmp")
data = im.load()
data[1,1] = 1
「ValueError: 画像は読み取り専用です」と報告されます。この例外が発生するのは、8 ビットのグレースケール bmp イメージのみです。なんで?ところで、8 ビット グレースケールの bmp イメージからパレットを取得できません。しかし、BMP 仕様によれば、パレットが存在します。なんで?
2番目の質問から始めましょう。基本的に、パレットを含むBMPファイルをロードする場合、PILは、そのパレットに、値がすべて等しくないrgbトリプルが少なくとも1つ含まれているかどうかを確認します。すべてのトリプルが等しい場合、グレースケールイメージが想定され、パレットは作成されないためim.palette
、この状況では常に空になります。
最初の質問については、おそらく「なぜ」を知りたくないでしょうが、それを修正する方法は、私は推測します。それ以外の場合、読み取り専用イメージを取得する単純な理由は、PILの内部詳細によるものです。グレースケールbmpはメモリマップされ、PILはそのための読み取り専用モードのみをサポートします(これはWindowsの問題を処理するためだけに行われるようです)。この問題の「修正」は簡単ですが、完全に良いわけではありません。画像を何らかのモードに変換すると、読み取り専用ではなくなります。'L'(あなたの場合は現在のモード)に変換することもできます。
PILで画像を処理する必要がある場合、通常は特定のモードで画像が必要になるため、これに問題があったことを覚えていません。そのため、必要なモードは常にimg.convert(X)
ですX
。