1

I make an Image Object of QImage from PIL and show it on the screen.

PIL has "RGB(24-bit)","RGBA(32-bit)","P(8-bit-index mode(palette mode))","L(8-bit)","1(1-bit)" Image-Format is available to QImage.

With connection to it,QImage has also "Format_RGB888(24-bit)","Format_ARGB(32-bit)","Format_Indexed8(8-bit)","Format_Mono(1-bit)".

I make an QImage object with connection to PIL Image Format.

For example, when I get "RGB" format from PIL Image, I put an argument as "Format_RGB888" on the fifth of QImage constructor as the QImage "RGB" format.

The problem is when I get "P", I make an QImage and show it, the image is always changed to grayscale.

I designated "Format_Indexed8" because "P" is 8-bit depth and there is no other adoptable format in QImage Formats.

Here is the 8-bit Image , "P" format by PIL.

Flag_Of_Debar.png

this image's name is Flag_Of_Debar.png.

But as the result of execution, the image is changed to it.

enter image description here

I seperate my code by PIL format as follows. Except for "P", no problem

Why is the 8-bit "P" mode PIL-Image changed to grayscale?

and what should I do?

from PySide import QtGui,QtCore
import os,sys
from PIL import Image
import numpy as np
import io
def main():
    app = QtGui.QApplication(sys.argv)
    directory = os.path.join(os.getcwd(),"\\icons\\")
    filename = QtGui.QFileDialog().getOpenFileName(None,"select icon",directory,"(*.png *.jpg *.bmp *.gif)","(*.png *.jpg *.bmp *.gif)")[0]
    im = Image.open(filename)
    print(im.mode)
    data = np.array(im)
    img_buffer = io.BytesIO()
    im.save(img_buffer,"BMP")
    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_ARGB32)
        #for avoiding RGB BGR change problem 
        qimagein.loadFromData(img_buffer.getvalue(), "BMP")               
    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)

    w = QtGui.QLabel()
    pix = QtGui.QPixmap.fromImage(qimagein)
    w.setPixmap(pix)  
    w.show()
    sys.exit(app.exec_())
if __name__ == "__main__":
    main()
Haru
  • 1,884
  • 2
  • 12
  • 30

2 Answers2

1

The Pillow fork of PIL has a method of converting to a QImage directly.

from PIL import ImageQt
qimagein = ImageQt.ImageQt(im)
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Thank you very much, in fact, I tried to do it Before. But An error returns as follows:pix = QtGui.QPixmap.fromImage(qimagein) TypeError: 'PySide.QtGui.QPixmap.fromImage' called with wrong argument types: `PySide.QtGui.QPixmap.fromImage(ImageQt) Supported signatures: PySide.QtGui.QPixmap.fromImage(PySide.QtGui.QImage, PySide.QtCore.Qt.ImageConversionFlags = Qt.AutoColor)`I should convert `ImageQt` to `QImage` object. So I once give it up, but you answered like above ,so I'll try to find a clue. – Haru Jun 28 '18 at 03:03
1

In that special case you must set the palette:

elif im.mode == "P":
    qimagein = QtGui.QImage(data.data, data.shape[1], data.shape[0], data.strides[0], QtGui.QImage.Format_Indexed8)
    pal = im.getpalette()
    l = [QtGui.qRgb(*pal[3*i:3*(i+1)]) for i in range(256)]
    qimagein.setColorTable(l)

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241