前提・実現したいこと
png形式の画像ファイルをtiff形式に変換するプログラムを作成しています。
作成し実行したところ、以下のようにエラーメッセージが出ました。
このstruct.error: argument out of rangeの解決の仕方を教えていただきたいです。
発生している問題・エラーメッセージ
Traceback (most recent call last): File "C:\Users\User\Desktop\MAP\pngtiff.py", line 4, in <module> im.save('kyushu65.tiff') File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\Image.py", line 2240, in save save_handler(self, fp, filename) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 1756, in _save offset = ifd.save(fp) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 905, in save result = self.tobytes(offset) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 850, in tobytes data = self._write_dispatch[typ](self, *values) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 681, in <lambda> b"".join(self._pack(fmt, value) for value in values) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 681, in <genexpr> b"".join(self._pack(fmt, value) for value in values) File "C:\Users\User\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\PIL\TiffImagePlugin.py", line 648, in _pack return struct.pack(self._endian + fmt, *values) struct.error: argument out of range
該当のソースコード
Python
1from PIL import Image 2Image.MAX_IMAGE_PIXELS = 3000000000 3im = Image.open('before.png') 4im.save('after.tiff')
試したこと
・扱う画像が大きい(38250*69750)ことが原因ではないかと考え、Image.MAX_IMAGE_PIXELSを追加
・エラーメッセージに"...\PIL\TiffImagePlugin.py"とあったのでPillowのライブラリを更新
補足情報(FW/ツールのバージョンなど)
Python 3.9.7 64bit
Pillow 8.4.0
VSCODE 1.61.2
> 扱う画像が大きい(38250*69750)ことが原因ではないかと考え
画像はカラーでしょうか?
それともグレースケールでしょうか?
また、何bitでしょうか?
(カラーの場合は1色あたり)
画像が8bitのグレースケールだと仮定して、そんなに大きなサイズの画像は持ってないので、下記のようにPython内で生成して確認してみたら、当方のWin 10のPython 3.7(64bit)では実行可能でした
from PIL import Image
im = Image.new("L", (38250, 69750))
im.save('after.tiff')
画像が8bitのカラーの場合は、下記のようにして確認したら、質問と同じエラーが出ました
from PIL import Image
im2 = Image.new("RGB", (38250, 69750))
im2.save('after2.tiff')
im2 = Image.new("RGB", (20525, 69750))
では大丈夫でしたが、
im2 = Image.new("RGB", (20526, 69750))
ではエラー出ました
当方のWin 10のPythonで出たエラーは質問と同じ
struct.error: argument out of range
でしたが、Macでは違うエラー
struct.error: 'L' format requires 0 <= number <= 4294967295
が出ました
> im2 = Image.new("RGB", (20525, 69750))
では大丈夫でしたが、
の場合の画素数は
20525*69750*3 = 4294856250
で、上記の「4294967295」を超えてません
> im2 = Image.new("RGB", (20526, 69750))
ではエラー出ました
の場合の画素数は
20526*69750*3 = 4295065500
で、上記の「4294967295」を超えてます
4294967295 = 2**32 - 1
なので、画素数が符号無し32bitで扱える数を超えたらダメなようです
jbpb0さん
画像は16bitグレーのものです。
なるほど。画素数が大きすぎるとダメなのですね。
いったんこちらで改めて小さい画像だったり2*32より大きいMAX_IMAGEなどで試したりしてみます。
> 画像は16bitグレー
im = Image.open('before.png')
のすぐ下に下記を追加して実行したら、何て表示されますでしょうか?
print(im.size)
print(im.mode)
> 画像は16bitグレー
https://pillow.readthedocs.io/en/stable/handbook/concepts.html
に「I;16 (16-bit unsigned integer pixels)」と書かれてるので、それで下記のようにして確認したら、エラー出ました
from PIL import Image
im3 = Image.new("I;16", (38250, 69750))
im3.save('after3.tiff')
im3 = Image.new("I;16", (30788, 69750))
では大丈夫でしたが、
im3 = Image.new("I;16", (30789, 69750))
ではエラー出ました
16bitの1画素を8bitの2画素と考えて、画素数を2倍にして計算してみます
上記の大丈夫な最大は「30788*69750*2 = 4294926000」で、「4294967295 = 2**32 - 1」以下です
ダメな最小は「30789*69750*2 = 4295065500」で、「4294967295 = 2**32 - 1」を超えてます
16bit画像の場合は、16bitの1画素を8bitの2画素と考えて画素数を計算して、それが符号無し32bitで扱える数を超えたらダメなようです
> 2*32より大きいMAX_IMAGEなどで試したり
「Image.MAX_IMAGE_PIXELS」を設定しなくても、
from PIL import Image
im3 = Image.new("I;16", (38250, 69750))
im3.save('after3.png')
は大丈夫なので、Pillow自体は扱える画素数だけど、エラーが出てる「TiffImagePlugin.py」がその画素数を扱えないのではないですかね
実際、
Image.MAX_IMAGE_PIXELS = None
を実行しても、Tiffの場合はエラー消えませんし
print文の箇所では(38250, 69750) I
と表示されました。
Iなのでもしかしたらbefore画像の作成時点でどこかミスがあったかもしれません。
16bitのTiffだと画素数が2^32-1を超えるとダメなのですね。
こちらでもhightとwidthを割り、リサイズしてある程度小さくすると無事に通りました。
どのみちリサイズも検討していたので今回はそれでいこうと思います。
> Iなのでもしかしたらbefore画像の作成時点でどこかミスがあったかもしれません。
https://pillow.readthedocs.io/en/stable/handbook/concepts.html
に「I (32-bit signed integer pixels)」と書かれてて、16bitグレースケールのデータ(符号無し16bit)は符号有り32bit変数に格納できるので、大丈夫ではないですかね
知らんけど
質問者さんが書いた回答で「自己解決」にしていいですよ
自己解決にさせていただきました。
改めましてこの度は本当にありがとうございました。
回答1件
あなたの回答
tips
プレビュー