45103


`PIL`と`numpy`を使用してイメージの配列を取得しています。  
その情報を、`QImage`のコンストラクタに渡して、`Image`オブジェクトをこさえています。  
その時、`QImage`のコンストラクタの第五引数に対して、フォーマットの情報を渡します。  
例えば、`24bit`の画像に対しては、`QtGui.QImage.Format_RGB888`を渡します。  
変換の目安としては、PILの場合、"L"が８bitを、”RGB"が`24bit`を、"RGBA"が`32bit`を表わし、`mode`を取得して、"L"か"RGB"か、"RGBA"かで適用するフォーマットを分けていました。

[code]

        #filenameはimageの名前あるいはディレクトリ
        im = Image.open(filename)
        print(im.mode)
        data = np.array(im)
        if im.mode == "RGB":            
            qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_RGB888)
        elif im.mode == "RGBA":
            qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_RGB32)
        elif im.mode == "1":
            qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_Mono)
        elif im.mode == "L":
            qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_Indexed8)
        elif im.mode == "P":
            qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_Indexed8)
    
[/code]

この時、PというModeが帰って来たものですから、[Pillowのチートシート](https://qiita.com/pashango2/items/145d858eff3c505c100a)で確認したところ、  
`8bit`だけれども、パレットモードだということです。  
これがオリジナルの8bitのイメージなのですけれども、  
[![画像の説明をここに入力](https://i.stack.imgur.com/zLfHk.png)](https://i.stack.imgur.com/zLfHk.png)  
上記の処理に載せた後に、イメージを描画すると、  
[![画像の説明をここに入力](https://i.stack.imgur.com/ogVPI.png)](https://i.stack.imgur.com/ogVPI.png)  
こんな感じでモノクロになります。  
`8`ビットを描画するために指定するフォーマットとしては、  
`Format_Indexed8`くらいしかなさそうなんですけれども、  
あきらめるしかないでしょうか？  
[PySide
QImage](http://pyside.github.io/docs/pyside/PySide/QtGui/QImage.html#PySide.QtGui.PySide.QtGui.QImage.convertToFormat)  
Pillowの公式サイトで、PillowはQt系のImageコンストラクタの処理と連携しており、  
"1","L","P","RGB","RGBA"の5つのモードには対応している。  
これ以外のモードを扱うには、`convert`を行えと書いてあるのですが、  
"P"も対応しているようです。しかし、肝心の、どのフォーマットに当てはめればいいのかが  
わかりません。  
"RGB"の場合は問題ないのですが、"RGBA"の場合だと、若干色が変化することもあります。

例えば、  
[![画像の説明をここに入力](https://i.stack.imgur.com/oOuBi.png)](https://i.stack.imgur.com/oOuBi.png)  
が、RGBAとして割り振られたコードを追加した後だと、  
[![画像の説明をここに入力](https://i.stack.imgur.com/deUwF.png)](https://i.stack.imgur.com/deUwF.png)  
こんな風に、一部の色が完全に違うものになってしまいます。  
これはどうしてなのかも知りたいです。  
[Pillow ImageQt
Module](https://pillow.readthedocs.io/en/5.1.x/reference/ImageQt.html?highlight=convert)

1．8bitのパレットモードの画像を、オリジナルと同様に表示する方法  
2．RGBAの場合に色が変化する原因と、対処法


CC BY-SA 4.0
2018-06-27T05:30:51.737
45097
2018-06-28T13:18:08.490
2018-06-27T13:16:32.657
24284
24284
question
python pyqt pyside pillow
ビットの深さに応じて処理を振り分けたい


`QImage`生成時に指定するフォーマットは「`QtGui.QImage.Format_Indexed8`」でよいと思います。(質問文で挙げられているPNGファイルで直接`QImage`を生成すると`format()`メソッドは`QtGui.QImage.Format_Indexed8`を返すので)

ただし、8bitフォーマットの場合、「`setColorTable()`」でカラーテーブル(パレット)を設定する必要があるようです。  
ですので、Pillowで生成したイメージデータからパレットデータを取得して(`im.getpalette()`)、生成した`QImage`データに`setColorTable()`で設定すれば、期待通りの色で表示されると思います。

* * *

追記(訂正あり)  
RGB形式のPNGファイルについて、`im.getpalette()`で取得できるのは、`R,G,B`の値が並んだ配列と思います。

[code]

    R0,G0,B0,R1,G1,B1, ... ,Rn,Gn,Bn
    (0...nはパレットのインデクス)
    
[/code]

一方、`QImage.setColorTable()`で指定するのは`RRGGBB`の整数値の配列と思います。  
なので、変換して設定する必要があるかと思います。

＃アルファ値は255として、以下のように計算すればよいです。

[code]

    255 * 0x1000000 + R値 * 0x10000 + G値 * 0x100 + B値
    
[/code]


CC BY-SA 4.0
2018-06-27T10:36:15.640
45103
2018-06-28T13:18:08.490
2018-06-28T13:18:08.490
20098
20098
45097
answer