def numpy_to_QImage(array, QImage_format=None): """ Transform numpy array into QImage. Data copy is avoided if possible. The QImage.data attribute contain the underlying numpy array to prevent python freeing that memory while the image is in use. (same or a copy of the given array, if copy was needed ) """ if numpy.ndim(array) == 2: h, w = array.shape if (QImage_format is None) or ( QImage_format is QImage.Format_Indexed8 ): # lent pour affichage sur QWidget par contre rapide pour QGlWidget qimage = QImage( numpy.require(array, numpy.uint8, "C").data, w, h, QImage.Format_Indexed8, ) qimage.setColorTable(grayTable) qimage.data = array return qimage elif QImage_format is QImage.Format_RGB32: bgrx = numpy.require( array * 65793, numpy.uint32, "C") # 0.7 a 0.9 msec (65793 = (1<<16)+(1<<8)+1) qimage = QImage(bgrx.data, w, h, QImage.Format_RGB32) qimage.data = ( bgrx # permet de garder un reference de l'image et lui eviter un destruction qui fait planter PySide2 ) return qimage elif QImage_format is QImage.Format_ARGB32: bgra = numpy.empty((h, w, 4), numpy.uint8, "C") # 0.01 mec bgra[..., 0] = array bgra[..., 1] = array # 0.38 msec bgra[..., 2] = array bgra[..., 3] = 255 qimage = QImage(bgra.data, w, h, QImage.Format_ARGB32) qimage.data = bgra return qimage elif numpy.ndim(array) == 3: h, w, channels = array.shape if channels == 3: bgrx = numpy.empty((h, w, 4), numpy.uint8, "C") bgrx[..., :3] = array qimage = QImage(bgrx.data, w, h, QImage.Format_RGB32) qimage.data = bgrx return qimage elif channels == 4: bgrx = numpy.require(array, numpy.uint8, "C") qimage = QImage(bgrx.data, w, h, QImage.Format_ARGB32) qimage.data = bgrx return qimage else: raise ValueError( "Color images can expects the last dimension to contain exactly three (R,G,B) or four (R,G,B,A) channels" ) else: raise ValueError("can only convert 2D or 3D arrays")
def cmap2pixmap(cmap, steps=50): """Convert a Ginga colormap into a QPixmap """ inds = numpy.linspace(0, 1, steps) n = len(cmap.clst) - 1 tups = [ cmap.clst[int(x*n)] for x in inds ] rgbas = [QColor(int(r * 255), int(g * 255), int(b * 255), 255).rgba() for r, g, b in tups] im = QImage(steps, 1, QImage.Format_Indexed8) im.setColorTable(rgbas) for i in range(steps): im.setPixel(i, 0, i) im = im.scaled(128, 32) pm = QPixmap.fromImage(im) return pm
def set_layer(self, name, array=None, composition='sourceover'): if array is None: if name in self.layers.keys(): self.layers.pop(name) return assert array.ndim == 2 assert array.dtype in ['uint8', 'bool'] height, width = array.shape compmode = COMPMODE[composition.lower()] qimage = QImage(memoryview(array), width, height, width, QImage.Format_Indexed8) qimage.setColorTable(imconvert.make_color_table('mask')) self.layers[name] = { 'array': array, 'qimage': qimage, 'composition': compmode }