バグ?:正常に透過されない透明色が有効なPNGセル

Issue #723 resolved
暗黒 騎士 created an issue

攻略wikiにコメントがあったので引用します。

leefes様の『竜追都市スターヴェス』ver1.01をpy3.0β4でプレイすると、表通りと裏通りの背景表示がおかしくなります(具体的には、背景セルに使われているフレーム素材の「透明色を使用する」がONになっていたために起こった不具合でした)。この症状はすでに作者様にも報告しましたが、エンジンver1.50で正常に動作しているシナリオがpyで表示上の不具合を起こすのは、1.50互換を謳っているpy側の不具合ともいえないか?と考え、一応こちらにも報告します。 -- 名無しさん (2018-10-27 12:51:55)

Comments (19)

  1. 暗黒 騎士 reporter

    自分の方でも追試しましたが、2.3でも3.0βと同様の表示でした。原因の画像は256色で255,255,255のパレットが複数あるPNGのようです。 以前もPNG関係の修正があったと記憶していますが、たぶん条件式関連でしょうか。

    参考:pull request #1895

  2. 暗黒 騎士 reporter

    あれ?すいません、勘違いしていました。

    セルで透明色を使うにチェックを入れると左上のピクセルが透過色として扱われるはず…ですよね。たしか1.50ではPNGで透過色が有効にならないバグがあって、本来の透過色が無効化されているPyの方が正しい挙動なので合わせていないということになるでしょうか。

  3. k4nagatsuki repo owner

    pull request #2300

    ご報告ありがとうございます。

    PNGイメージは256色以下でもパレットの任意の色を透過色に指定する事ができますが、その指定が無視される状態になっていました。GIF関連でいろいろ手入れした結果が誤爆したようです。修正しました。

    なお、そのような透過設定が入ったイメージを扱う場合は、セルのマスク指定は無視されます(GIF以外)。

    cwxeditorにも似たような問題があって、その原因が1.29で背景セルで表示がおかしくなるので特殊な処理をする、という部分だったのですが、CWPyでは特に同様の処理をしておらず謎です。とりあえずその処理は消してしまったのですが、そのせいで問題が出ているのを見かけたら改めてお知らせください。

  4. 暗黒 騎士 reporter

    cardwirthpy_20181028_x64.zipと上記シナリオで動作確認を行ったのですが、依然として白いままに見えます。 というか、上記報告にもありますが、以前のPyでも「透明色を使う」にチェックが入っていなければこの256色PNGの透過は正常に行われている=256色以下でも透過色自体は正常に読み取れているように見えます。「透過色を持つPNGはエディタ上でのセルのマスク指定に拘わらず(無視されて)透過される」というのが正常な挙動なのであれば「セルのマスク指定が反映されている」のが原因ではないでしょうか?

    アプデの方法が以前と違う&画像関係には明るくないのでなにか見たて違いをしていたらすいません…。

  5. k4nagatsuki repo owner

    手元の動作と違うので確認させてください。

    手元では、最初の表示は問題なく、二度目のキャッシュを用いた時に問題が再発します。どうもSurfaceをコピーするとだめなようです。pygameのバグとしか思えないのですが、対策は可能です。しかし、@akkwさんの環境では最初から問題が発生しているとなると、モニタの設定など何か根本的に別の理由があるのかもしれません。

    「透明色を使う」にチェックが入っていなければこの256色PNGの透過は正常に行われている

    問題が発生するのはマスク処理を行う部分で、この処理自体が実行されないためです。と思ったのですが、Surfaceのコピーは行われるので、これも現時点ではよく分からないです。

  6. k4nagatsuki repo owner

    pull request #2301

    上記した対策です。一番最初の正常に描画できるものを別のSurfaceに描画して以降はそれを取り回すという方法なので、最初から正しく表示されない場合はこの対策は意味をなさないはずです。

  7. k4nagatsuki repo owner

    「透明色を使う」にチェックが入っていなければこの256色PNGの透過は正常に行われている

    この部分ですが、一度convert()を行った(モニタの色情報に合わせた≒24-bitにした)Surfaceでは、パレット由来の問題が消えるためか、copy()で透過色が失われる問題が起きないようです。

    ただ、このイメージは同じ色が複数あるので、パレット情報を喪失する(=256色を超える色数にする)と透過状態がおかしくなります。具体的には、外枠の白いはずの1ピクセルの線が透けて見えます。正常なように見えて実は壊れているので、これはこれで対策が必要です。

  8. 暗黒 騎士 reporter

    CardWirthPy 3.0 Beta 3 (64-bit) Build: 2018-10-28 09:36:15で再度確認しましたが、 シナリオに入った最初から真っ白です。見え方が異なるようなのでSSをアップしました。(後で削除します) よく見ると透過されていないのではなく、このPNG画像緑のテーブル素材で透過されているパレットが異なっているようですね。1.50では複数のパレットが透過されている?

    Py最新 https://bitbucket.org/akkw/cardwirthpy-reboot/downloads/py3b_2018-10-28%20093615.JPG

    1.50 https://bitbucket.org/akkw/cardwirthpy-reboot/downloads/150.JPG

  9. k4nagatsuki repo owner

    モニタ設定の問題でしょうか? ファイルが違うんでしょうか? 私のところでの当該ファイルのMD5ハッシュは65a4ffb1c1f4631ae36c843fcd48bee6です。

    1.50の表示は、よく見ると私の手許でも同じでした。「正常なように見えて実は壊れている」が1.50的には正解なようです。

    マスクを使用しない時に同じ表示になるのであれば、条件に合うイメージは常にマスク設定を無視すればよさそうです。

  10. 暗黒 騎士 reporter
    MD5 ハッシュ (ファイル.png):
    65a4ffb1c1f4631ae36c843fcd48bee6
    CertUtil: -hashfile コマンドは正常に完了しました。
    

    同一ファイルのようです。自分のマシンの環境依存だとするとcx_Freezeの仕様的に干渉するのかはわかりませんが、Python2とPython2用のpygame ver1.9.2が入っているぐらいでしょうか。モニタはDVI-D接続のFHD、一般的な設定だと思います。

  11. k4nagatsuki repo owner

    マスクを使用しない時に同じ表示になるのであれば、条件に合うイメージは常にマスク設定を無視すればよさそうです。

    このバージョンは1.50と同様に動くか確認していただけないでしょうか。

    https://bitbucket.org/k4nagatsuki/cardwirthpy-reboot-k4nagatsuki/downloads/CardWirthPy_test_20181028a.zip


    以下余談です。

    CardWirth 1.28~1.50には、今回のイメージでパレットが失われた時に透過色が壊れるようなものや、他の色々なイメージ関係のバグがあり、CWPyも仕方なくそれに合わせています。そして「クラシックから変換した時になるべくそのまま動いた方がいい」という理由からWSN形式でも同様に動きます。

    しかし、こうバグがあると、イメージの作者は正しく作ったのにバグのせいで意図通りに表示されないというケースが当然出てきます。そのうち、WSNに「CardWirth 1.**互換のイメージ表示を行う」というようなオプションをつけて、互換性維持の世界に閉じ込めてしまった方がいいかもしれません。

  12. k4nagatsuki repo owner

    試していただきたいのですが、上の版のsrc.zipに含まれているutil.pyで745行目にあるimage.convert()の直前に以下のような処理を入れるとどうなるか見ていただけないでしょうか。

    また、マスクを指定しなかった場合にはどうなるかも見ていただけないでしょうか。

        if image.get_bitsize() <= 8 and image.get_colorkey() and not isgif:
            mask = False
    
  13. 暗黒 騎士 reporter

    上の版のsrc.zipに含まれているutil.pyで745行目にあるimage.convert()の直前に以下のような処理を入れると

    すいません、自分はPython3の実行環境を入れていないせいかソースから実行できませんでした。 ただ自分のフォークで試した感じではその文の挿入で正常になりました。

    https://bitbucket.org/akkw/cardwirthpy-reboot/downloads/pylite_mask_False.JPG

    また、マスクを指定しなかった場合

    シナリオ側の「透明色を使用」設定をCWXEditorで解除した場合という意味で合っているでしょうか? 先ほどのCardWirthPy 3.0 Beta 3 (64-bit) Build: 2018-10-28 10:44:09での表示はこうなります。(正常)

    https://bitbucket.org/akkw/cardwirthpy-reboot/downloads/py3btest_cell_maskoff.JPG

  14. k4nagatsuki repo owner

    pull request #2303

    上のコードをマージしました。正直なぜこれで1.50と同様に動くのかよく分からないのですが、これで確認をお願いします。

  15. k4nagatsuki repo owner

    どうも釈然としませんがとりあえず合ったようですね。

    ご確認ありがとうございます。

  16. Log in to comment