mieki256's diary



2016/11/26() [n年前の日記]

#2 [python] Windows + PySide + Pillow(PIL)の組み合わせでImageQtの動作が怪しい

Windows10 x64 + Python 2.7.12 + PySide 1.2.4 + Pillow(PIL) 3.4.2 の環境で、Pillow に入ってる ImageQt を使って PIL Image を PySide の QImage に変換しようとしていたのだけど、Python が強制終了・crashしまくることに気づいて悩んだり。

ちなみに、PySide 1.2.4 と PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe を両方インストールしてある環境。

例えば、以下のソースと画像を使って実験すると…。

_imageqt_test.py
u"""
Pillow(PIL)のImageQtについて動作確認.

動作確認 : Windows10 x64 + Python 2.7.12 + PySide 1.2.4 + Pillow 3.4.2
"""

use_pyside = True

import sys

if use_pyside:
    # use PySide

    # import PySide
    # sys.modules['PyQt4'] = PySide

    # ここでPyQt4を使わないようにしているはず…なのだが…
    from PySide import QtGui
    from PySide import QtCore
    sys.modules['PyQt4.QtGui'] = QtGui
    sys.modules['PyQt4.QtCore'] = QtCore

    from PySide.QtCore import *  # NOQA
    from PySide.QtGui import *   # NOQA
else:
    # use PyQt4
    from PyQt4.QtCore import *  # NOQA
    from PyQt4.QtGui import *   # NOQA

from PIL import Image
from PIL import ImageQt


class MyWidget(QWidget):

    def __init__(self, *argv, **keywords):
        super(MyWidget, self).__init__(*argv, **keywords)

        layout = QGridLayout()

        lst = [
            "./tmp_grayscale.png",
            "./tmp_indexed.png",
            "./tmp_rgb.png",
            "./tmp_rgba.png"
        ]

        for i, fpath in enumerate(lst):
            im = Image.open(fpath)
            old_im_mode = im.mode

            if im.mode != "RGBA":
                im = im.convert("RGBA")
            print("im.mode %s -> %s" % (old_im_mode, im.mode))

            qim1 = ImageQt.ImageQt(im)

            qim2 = QImage(qim1)
            pm = QPixmap.fromImage(qim2)
            lbl = QLabel(old_im_mode, self)
            lbl.setPixmap(pm)
            layout.addWidget(lbl, i / 2, i % 2)

        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWidget()
    w.show()
    sys.exit(app.exec_())

_tmp_grayscale.png
_tmp_indexed.png
_tmp_rgb.png
_tmp_rgba.png

やってることは、 してるだけ、のはずだけど。

コレを実行すると、Python が死ぬ。
python_crash_ss.png


これがまたよく分からんのだけど、PySide を使わずに PyQt4 を使うと Python が死なずに動いちゃう。

use_pyqt4_result_ss.png

最初のあたりの use_pyside = True を use_pyside = False にすると、PyQt4 を使って動かせる。

各行をコメントアウトして動作確認してみたけど、どうも QPixmap.fromImage() を呼んだ時点で Python が死んでる感じ。QPixmap.fromImage() をコメントアウトすると Python が死なないわけで。

すると ImageQt が QImage を返せていないのか、おかしな QImage を QPixmap.fromImage() に渡してしまっているのか。と思ったけど、 _Pillow/ImageQt.py at master - python-pillow/Pillow を眺めると、ImageQt は QImage を継承してるわけで…。github上の ImageQt.py と、手元の ImageQt.py は、どちらも似たようなソースだし…。

アレ? 待てよ? 微妙に違うな。

_Pillow 2.9 causes PySide application to crash (whereas 2.8.2 does not) - Issue #1370 - python-pillow/Pillow

上記のバグ報告ページで、self.__data = im_data['data'] を追加してソレを使って QImage を生成すると落ちない、という報告が。手元の ImageQt.py はその行が入ってない。

手元の ImageQt.py にも試しに反映させてみたら、落ちなくなった。

しかし困ったな…。これでは他の環境にスクリプトを持っていった際に ImageQt が使えないではないか…。一々、「ImageQt.py をエディタで開いて該当行を修正してください」とお願いするのもアレだし…。

以上です。

過去ログ表示

Prev - 2016/11 - Next
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project