Convert numpy array to PySide QPixmap

前端 未结 4 900
借酒劲吻你
借酒劲吻你 2020-12-08 16:59

I want to convert an image into a NumPy array to a PySide QPixmap, so I can display it (EDIT: in my PySide UI). I already found this tool: qimage2ndarray, but it only works

相关标签:
4条回答
  • 2020-12-08 17:17

    In addition to @user545424 answer about using PIL, if you didn't want to depend on PIL, you could manually construct your Image directly from your np array:

    width = 100
    height = 100
    data = np.random.randint(0,256,size=(width,height,3)).astype(np.uint8)
    
    img = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
    for x in xrange(width):
        for y in xrange(height):
            img.setPixel(x, y, QtGui.QColor(*data[x][y]).rgb())
    
    pix = QtGui.QPixmap.fromImage(img)
    

    I'm sure, using PIL, there is a way to read the actual image data into a QImage, but I will let @user545424 address that part since its from his answer. PIL comes with the ImageQt module which is convenient for directly converting an Image -> QPixmap, but unfortunately thats a PyQt4 QPixmap, which doesn't help you.

    0 讨论(0)
  • 2020-12-08 17:26

    If the answer of user545424 does not work as expected: you see artifacts in the image, then I would suggest you change the parameter to

    PySide.QtGui.QImage.Format_ARGB32

    a = np.random.randint(0,256,size=(100,100,3)).astype(np.uint32)
    b = (255 << 24 | a[:,:,0] << 16 | a[:,:,1] << 8 | a[:,:,2]).flatten() # pack RGB values
    im = PySide.QtGui.QImage(b, 100, 100, PySide.QtGui.QImage.Format_ARGB32)
    
    0 讨论(0)
  • 2020-12-08 17:33

    One alternative is to just use PIL library.

    >>> import numpy as np
    >>> import Image
    >>> im = Image.fromarray(np.random.randint(0,256,size=(100,100,3)).astype(np.uint8))
    >>> im.show()
    

    You can look at the QPixmap constructor at http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html.

    It looks like you should be able to use a numpy array directly in the constructor:

    class PySide.QtGui.QImage(data, width, height, format)

    where the format argument is one of these: http://www.pyside.org/docs/pyside/PySide/QtGui/QImage.html#PySide.QtGui.PySide.QtGui.QImage.Format.

    So, for example you could do something like:

    >>> a = np.random.randint(0,256,size=(100,100,3)).astype(np.uint32)
    >>> b = (255 << 24 | a[:,:,0] << 16 | a[:,:,1] << 8 | a[:,:,2]).flatten() # pack RGB values
    >>> im = PySide.QtGui.QImage(b, 100, 100, PySide.QtGui.QImage.Format_RGB32)
    

    I don't have PySide installed so I haven't tested this. Chances are it won't work as is, but it might guide you in the right direction.

    0 讨论(0)
  • 2020-12-08 17:34

    If you create the data yourself, using numpy for example, I think the fastest method is to directly access a QImage. You can create a ndarray from the buffer object QImage.bits(), do some work using the numpy methods and create a QPixmap from QImage when you are done. You can also read or modify existing QImages that way.

    import numpy as np
    from PySide.QtGui import QImage
    
    img = QImage(30, 30, QImage.Format_RGB32)
    imgarr = np.ndarray(shape=(30,30), dtype=np.uint32, buffer=img.bits())
    
    # qt write, numpy read
    img.setPixel(0, 0, 5)
    print "%x" % imgarr[0,0]
    
    # numpy write, qt read
    imgarr[0,1] = 0xff000006
    print "%x" % img.pixel(1,0)
    

    Be sure that the array does not outlive the image object. If you want, you can use a more sophisticated dtype, like a record array for individual access to the alpha, red, green and blue bits (beware of endianess though).

    In case there is no efficient way to calculate the pixel values using numpy, you can also use scipy.weave to inline some C/C++ code that operates on the array img.bits() points to.

    If you already have an image in ARGB format, creating the QImage from data as suggested before is probably easier.

    0 讨论(0)
提交回复
热议问题