Search code examples
pythonpyqtpyqt4

In PyQt, how do I convert QImage to a list of pixels?


I see the QImage.bits() function, and the QImage.constBits(), but both return a voidptr and I'm not sure in python what you can do with that. I am familiar with the C++ syntax, but not for python.

As for data type, i mean this: A black and white pixel would be equal to [[0,0,0],[255,255,255]] where the QImage is Format.RGB888


Solution

  • See the youtube video

    I hope that I understand your needs, here I put together an app. That will convert QImage to List of Quadruplets RGBA Value, I hope that it help you at least to figure out how to do it, you may implement it different for your needs, you may use matrix/matrix manipulation lib. Like NumPy or any other matrix manipulation lib.

    But, in this case I did not create any dependency, because I think is better to stay simple and if you need something more complex you can dig in...

    You going to need an image, to keep it simple I will provide 3 images, each of them with different size and pixel colors Image 1:
    Image 1Image 2:
    Image 2Image 3:
    Image 3

    You can also check my website to see the code

    Here Is the code:

    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    import sys
    
    
    class main_window(QDialog):
        def __init__(self):
            QDialog.__init__(self)
    
            # Create a QTextBrowser
            qtb_rgba = QTextBrowser(self)
            # Create an empty list
            li_pixels = list()
    
    
            #!! QImage to list of pixels !! >>> RGB format
            image = QImage()
            load_image = image.load("test_img_3x3", ".jpg")
            # Make sure you got an image named "test_img_3x3" .jpg extension , it needs to sit on your HDD,
            # in the root from where you run the script
            # create it with the size of 3x3 , do it in Paint, or any other 2d image manipulation software
    
            # An assert error will occur if fails to open your image
            assert load_image == True
    
            # Find more data about our image
            # In our case is obvios that we create with our hand an image .jpg with a size of 3x3
            # Even so, the functions bellow will may help us sometimes
    
            # Obtain image size
            image_width = image.width()
            image_height = image.height()
            print("Your image size is:\nWidth: " + str(image_width) + " Height: " + str(image_height) + "\n" + str(image_width) + "x" + str(image_height))
    
    
            # Get QRGB values
            qrgb = image.pixel(0, 0)
            print("QRGB Values: " + str(qrgb))
            # Convert it to QColor
            qrgb_to_QCol = QColor(qrgb)
            # Once you got it converted in QColor you got a lot of freedom to choose from,
            # you can convert it to some of the most popular formats like:
            # CMYK, HSL, RGB, RGBA, magenta, or even individual chanels R , G , B  + a lot of other formats, even Floats...
    
            # Convert it to RGBA
            rgba = qrgb_to_QCol.getRgb()
            print("RGBA Values: " + str(rgba))
    
            # In order to achieve our goal: list of pixels for the entire image
            # we got many ways to achieve it, depending of your needs you may implelent it different
            # I will continue by producing a list of quadruplets values, 
            # from left to right - top to bottom 
    
            # The Quadruplets value for the list will be, which mean that 0 will hold value 0 on list , 1 hold 1 and so on...
            # y _ _
           #x|0 1 2
            #|3 4 5
            #|6 7 8
    
            # And the position will be:
            # y     _     _
           #x|0.0   1.0   2.0
            #|0.1   1.1   2.1
            #|0.2   1.2   2.2
    
            # So let`s do it
    
            # Generate a list of numbers for width
            li_num_width = []
            for i in range(image_width):
                li_num_width.append(i)
    
            # Generate a list of numbers for height
            li_num_height = []
            for i in range(image_height):
                li_num_height.append(i)
    
            # List for x num
            x = [li_num_width for i in range(len(li_num_height))]
            print("\nX list is:\n" + str(x))
    
            # List for y num
            for i in range(len(li_num_height)):
                y = [[i]*len(li_num_width) for i in range(len(li_num_height))]
            print("\nY list is:\n" + str(y))
    
            
            row_el_li = []
            row_el_li_y = []
    
            # Obtain list numbers for x
            for i in range(len(li_num_height)):
                row = x[i]
                for i in range(len(li_num_width)):
                    row_el = row[i]
                    #print(row_el)
                    row_el_li.append(row_el)
    
            print("\nRow Elements list x: \n" + str(row_el_li))
            
            # Obtain list numbers for y
            for i in range(len(li_num_height)):
                row_y = y[i]
                for i in range(len(li_num_width)):
                    row_el_y = row_y[i]
                    #print(row_el_y)
                    row_el_li_y.append(row_el_y)
    
            print("\nRow Elements list y: \n" + str(row_el_li_y))
            
            # Create a list, which eventualy will hold qrgb values, which is our goal
            qrgb_li = []
            # How many values will the list hold? or How many pixels in the image do we have?
            num_pixels = len(li_num_width) * len(li_num_height)
            print("\nNumber of Pixels:" + str(num_pixels))
            
            for i in range(num_pixels):
                ordered_qrgb = image.pixel(row_el_li[i], row_el_li_y[i])
                qrgb_li.append(ordered_qrgb)
    
            
            # One more step lets convert from QRGB list to RGBA list, which will lead us to the end of this tutorial
            rgba_li = []
    
            for i in range(len(qrgb_li)):
                qrgb_li_to_QCol = QColor(qrgb_li[i])
                rgba_set = qrgb_li_to_QCol.getRgb()
                rgba_li.append(rgba_set)
    
            print("\nList of Quadruplets RGBA Value: \n" + str(rgba_li))
            
            
            #!! QImage to list of pixels End !!
    
            qtb_rgba.setText(str(rgba_li))
            #.......
            self.setFixedSize(250, 300)
            self.setWindowTitle("QImage to list of pixels")
    
    #.......3D Sasu Catalin
    app = QApplication(sys.argv)
    dialog = main_window()
    dialog.show()
    sys.exit(app.exec_())
    

    I hope that help you out, and if you need more details about this subject you can visit my website from time to time...