class ColorButton(QPushButton): """ Color choosing push button """ __pyqtSignals__ = ("colorChanged(QColor)",) def __init__(self, parent=None): QPushButton.__init__(self, parent) self.setFixedSize(20, 20) self.setIconSize(QSize(12, 12)) self.connect(self, SIGNAL("clicked()"), self.choose_color) self._color = QColor() def choose_color(self): rgba, valid = QColorDialog.getRgba(self._color.rgba(), self.parentWidget()) if valid: color = QColor.fromRgba(rgba) self.set_color(color) def get_color(self): return self._color @pyqtSignature("QColor") def set_color(self, color): if color != self._color: self._color = color self.emit(SIGNAL("colorChanged(QColor)"), self._color) pixmap = QPixmap(self.iconSize()) pixmap.fill(color) self.setIcon(QIcon(pixmap)) color = pyqtProperty("QColor", get_color, set_color)
def generateRandomColors(M=256, colormodel="hsv", clamp=None, zeroIsTransparent=False): """Generate a colortable with M entries. colormodel: currently only 'hsv' is supported clamp: A dictionary stating which parameters of the color in the colormodel are clamped to a certain value. For example: clamp = {'v': 1.0} will ensure that the value of any generated HSV color is 1.0. All other parameters (h,s in the example) are selected randomly to lie uniformly in the allowed range. """ r = numpy.random.random((M, 3)) if clamp is not None: for k,v in clamp.iteritems(): idx = colormodel.index(k) r[:,idx] = v colors = [] if colormodel == "hsv": for i in range(M): if zeroIsTransparent and i == 0: colors.append(QColor(0, 0, 0, 0).rgba()) else: h, s, v = r[i,:] color = numpy.asarray(colorsys.hsv_to_rgb(h, s, v)) * 255 qColor = QColor(*color) colors.append(qColor.rgba()) return colors else: raise RuntimeError("unknown color model '%s'" % colormodel)
def addNewLabel(self): """ Add a new label to the label list GUI control. Return the new number of labels in the control. """ numLabels = len(self._labelControlUi.labelListModel) if numLabels >= len(self._colorTable16) - 1: # If the color table isn't large enough to handle all our labels, # append a random color randomColor = QColor(numpy.random.randint(0, 255), numpy.random.randint(0, 255), numpy.random.randint(0, 255)) self._colorTable16.append(randomColor.rgba()) color = QColor() color.setRgba(self._colorTable16[ numLabels + 1]) # First entry is transparent (for zero label) label = Label(self.getNextLabelName(), color) label.nameChanged.connect(self._updateLabelShortcuts) self._labelControlUi.labelListModel.insertRow( self._labelControlUi.labelListModel.rowCount(), label) nlabels = self._labelControlUi.labelListModel.rowCount() # Make the new label selected selectedRow = nlabels - 1 self._labelControlUi.labelListModel.select(selectedRow) self._updateLabelShortcuts()
def addNewLabel(self): """ Add a new label to the label list GUI control. Return the new number of labels in the control. """ numLabels = len(self._labelControlUi.labelListModel) if numLabels >= len(self._colorTable16)-1: # If the color table isn't large enough to handle all our labels, # append a random color randomColor = QColor(numpy.random.randint(0,255), numpy.random.randint(0,255), numpy.random.randint(0,255)) self._colorTable16.append( randomColor.rgba() ) color = QColor() color.setRgba(self._colorTable16[numLabels+1]) # First entry is transparent (for zero label) label = Label(self.getNextLabelName(), color) label.nameChanged.connect(self._updateLabelShortcuts) self._labelControlUi.labelListModel.insertRow( self._labelControlUi.labelListModel.rowCount(), label ) nlabels = self._labelControlUi.labelListModel.rowCount() # Make the new label selected selectedRow = nlabels-1 self._labelControlUi.labelListModel.select(selectedRow) self._updateLabelShortcuts()
def initLabels(self): #Add the layer to draw the labels, but don't add any labels self.labelsrc = LazyflowSinkSource(self.workflow.labels, self.workflow.labels.outputs["Output"], self.workflow.labels.inputs["Input"]) self.labelsrc.setObjectName("labels") transparent = QColor(0,0,0,0) self.labellayer = ColortableLayer(self.labelsrc, colorTable = [transparent.rgba()] ) self.labellayer.name = "Labels" self.labellayer.ref_object = None self.layerstack.append(self.labellayer)
def addThresholdOperator(self): if self.opThreshold is None: self.opThreshold = OpThreshold(self.g) self.opThreshold.inputs["Input"].connect(self.pCache.outputs["Output"]) #channel, value = ThresholdDlg(self.labelListModel._labels) channel = 0 value = 0.5 ref_label = self.labelListModel._labels[channel] self.opThreshold.inputs["Channel"].setValue(channel) self.opThreshold.inputs["Threshold"].setValue(value) threshsrc = LazyflowSource(self.opThreshold.outputs["Output"][0]) threshsrc.setObjectName("Threshold for %s" % ref_label.name) transparent = QColor(0,0,0,0) white = QColor(255,255,255) colorTable = [transparent.rgba(), white.rgba()] threshLayer = ColortableLayer(threshsrc, colorTable = colorTable ) threshLayer.name = "Threshold for %s" % ref_label.name self.layerstack.insert(1, threshLayer) self.CCButton.setEnabled(True)
def save_layer_as_image(layer, extent, path_to_file, max_resolution='1024', image_type = 'tif'): """ Select and save the currently visible extent to a .tif file :param width: image width :type width: int :param height: image height :type height: int :param name: name of the created file :type name: str :return: :rtype: """ # calculate the extents width and height width = extent.width() height = extent.height() # calculate the missing value (width or height) of the output file, based on the extent if width >= height: height_as_dec = max_resolution / width * height width = max_resolution height = int(height_as_dec) else: width_as_dec = max_resolution / height * width width = int(width_as_dec) height = max_resolution # append the resolution to the filename and call the save method filename=layer.name() if filename.startswith("WMS_"): filename=filename.replace("WMS_","") else: resolution_prefix = '{}_{}-'.format(width, height) filename = resolution_prefix + layer.name() img = QImage(QSize(width, height), QImage.Format_ARGB32_Premultiplied) color = QColor(187, 187, 187, 0) img.fill(color.rgba()) leonardo = QPainter() leonardo.begin(img) leonardo.setRenderHint(QPainter.Antialiasing) renderer = QgsMapRenderer() lst = [layer.id()] renderer.setLayerSet(lst) renderer.setExtent(extent) renderer.setOutputSize(img.size(), img.logicalDpiX()) renderer.render(leonardo) leonardo.end() filename += '.{}'.format(image_type) out_path = os.path.join(path_to_file, filename) if img.save(out_path, image_type): return out_path
def getNextLabelColor(self): """ Return a QColor to use for the next label. """ numLabels = len(self._labelControlUi.labelListModel) if numLabels >= len(self._colorTable16)-1: # If the color table isn't large enough to handle all our labels, # append a random color randomColor = QColor(numpy.random.randint(0,255), numpy.random.randint(0,255), numpy.random.randint(0,255)) self._colorTable16.append( randomColor.rgba() ) color = QColor() color.setRgba(self._colorTable16[numLabels+1]) # First entry is transparent (for zero label) return color
def getNextCropColor(self): """ Return a QColor to use for the next crop. """ numCrops = self._maxCropNumUsed+1 if numCrops >= len(self._colorTable16)-1: # If the color table isn't large enough to handle all our crops, # append a random color randomColor = QColor(numpy.random.randint(0,255), numpy.random.randint(0,255), numpy.random.randint(0,255)) self._colorTable16.append( randomColor.rgba() ) color = QColor() color.setRgba(self._colorTable16[numCrops+1]) # First entry is transparent (for zero crop) return color
def _randomColors(self, M=256): """Generates a pleasing color table with M entries.""" colors = [] for i in range(M): if i == 0: colors.append(QColor(0, 0, 0, 0).rgba()) else: h, s, v = random.random(), random.random(), 1.0 color = numpy.asarray(colorsys.hsv_to_rgb(h, s, v)) * 255 qColor = QColor(*color) colors.append(qColor.rgba()) #for the first 16 objects, use some colors that are easily distinguishable colors[1:17] = colortables.default16 return colors
def initLabels(self): #Add the layer to draw the labels, but don't add any labels shape=self.inputProvider.outputs["Output"].shape self.opLabels = OpBlockedSparseLabelArray(self.g) self.opLabels.inputs["shape"].setValue(shape[:-1] + (1,)) self.opLabels.inputs["blockShape"].setValue((1, 32, 32, 32, 1)) self.opLabels.inputs["eraser"].setValue(100) self.labelsrc = LazyflowSinkSource(self.opLabels, self.opLabels.outputs["Output"], self.opLabels.inputs["Input"]) self.labelsrc.setObjectName("labels") transparent = QColor(0,0,0,0) self.labellayer = ColortableLayer(self.labelsrc, colorTable = [transparent.rgba()] ) self.labellayer.name = "Labels" self.labellayer.ref_object = None self.layerstack.append(self.labellayer)
def font_bmp_to_alpha(filename): image = QImage(filename) image = image.convertToFormat(QImage.Format_ARGB32_Premultiplied) # Because the game uses 8bit grayscale bitmaps for its fonts with white as # fully visible and black as fully transparent, I'm using a naive technique # that averages the RGB value of a pixel and sets that as its alpha value. # I'm sure this will do fun stuff to other images, but it does the job # for the game's fonts, and that's all that really matters. ヽ(´ー`)ノ for i in range(image.width()): for j in range(image.height()): color = QColor(image.pixel(i, j)) alpha = (color.red() + color.green() + color.blue()) / 3 color.setAlpha(alpha) image.setPixel(i, j, color.rgba()) return image
def matplotlib_to_qt4_colortable(cmap_name, N, asLong=True): """ get a colortable of desired N in Qt4 format as required from the colortable Layer cmap_name can be any matplotlib colortable """ try: import matplotlib.cm as cm except: raise RuntimeError("this function requires matplotlib") cmap = cm.get_cmap(cmap_name, N) cmap = cmap(np.arange(N))[:, :-1] colortable = [] for el in cmap: r, g, b = el * 255 color = QColor(r, g, b) if asLong: color = color.rgba() colortable.append(color) return colortable
def matplotlib_to_qt4_colortable(cmap_name,N, asLong=True): """ get a colortable of desired N in Qt4 format as required from the colortable Layer cmap_name can be any matplotlib colortable """ try: import matplotlib.cm as cm except: raise RuntimeError("this function requires matplotlib") cmap = cm.get_cmap(cmap_name, N) cmap=cmap(np.arange(N))[:,:-1] colortable = [] for el in cmap: r,g,b = el*255 color = QColor(r,g,b) if asLong: color = color.rgba() colortable.append(color) return colortable
def addLabel(self): color = QColor(numpy.random.randint(0,255), numpy.random.randint(0,255), numpy.random.randint(0,255)) numLabels = len(self.labelListModel) if numLabels < len(self._colorTable16): color = self._colorTable16[numLabels] self.labellayer.colorTable.append(color.rgba()) self.labelListModel.insertRow(self.labelListModel.rowCount(), Label("Label %d" % (self.labelListModel.rowCount() + 1), color)) nlabels = self.labelListModel.rowCount() if self.opPredict is not None: print "Label added, changing predictions" #re-train the forest now that we have more labels self.opPredict.inputs['LabelsCount'].setValue(nlabels) self.addPredictionLayer(nlabels-1, self.labelListModel._labels[nlabels-1]) #make the new label selected index = self.labelListModel.index(nlabels-1, 1) self.labelListModel._selectionModel.select(index, QItemSelectionModel.ClearAndSelect) #FIXME: this should watch for model changes #drawing will be enabled when the first label is added self.changeInteractionMode( 1 ) self.interactionComboBox.setEnabled(True)
class CColorPickerPopup(QFrame): __pyqtSignals__ = ('selected(QColor)', 'hid()') def __init__(self, width, withColorDialog, parent=None): super(QFrame, self).__init__(parent, Qt.Popup) self.setFrameStyle(QFrame.StyledPanel) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.setFocusPolicy(Qt.StrongFocus) self.setMouseTracking(True) self.cols = width if withColorDialog: self.moreButton = CColorPickerButton(self) self.moreButton.setFixedWidth(24) self.moreButton.setFixedHeight(21) self.moreButton.setFrameRect(QRect(2, 2, 20, 17)) self.connect(self.moreButton, SIGNAL('clicked()'), self.getColorFromDialog) else: self.moreButton = None self.eventLoop = None self.grid = None self.items = [] self.widgetAt = {} self.lastSel = QColor() self.regenerateGrid() def __del__(self): if self.eventLoop: self.eventLoop.exit() def find(self, col): for i in xrange(len(self.items)): if self.items[i] and self.items[i].color() == col: return self.items[i] return None def insertColor(self, col, text, index): existingItem = self.find(col) lastSelectedItem = self.find(self.lastSelected()) if existingItem: if lastSelectedItem and existingItem != lastSelectedItem: lastSelectedItem.setSelected(False) existingItem.setFocus() existingItem.setSelected(True) return item = CColorPickerItem(col, text, self) if lastSelectedItem: lastSelectedItem.setSelected(False) else: item.setSelected(True) self.lastSel = col item.setFocus() self.connect(item, SIGNAL('selected()'), self.updateSelected) if index == -1: index = len(self.items) self.items.insert(index, item) self.regenerateGrid() self.update() def insertColors(self, colList): lastSelectedItem = self.find(self.lastSelected()) for col, text in colList: existingItem = self.find(col) if existingItem: continue item = CColorPickerItem(col, text, self) # if lastSelectedItem: # lastSelectedItem.setSelected(False) # else: # item.setSelected(True) # self.lastSel = col # item.setFocus() self.connect(item, SIGNAL('selected()'), self.updateSelected) index = len(self.items) self.items.insert(index, item) self.regenerateGrid() self.update() def color(self, index): if index < 0 or index > (len(self.items) - 1): return QColor() return self.items[index].color() def exec_(self): self.show() e = QEventLoop() self.eventLoop = e e.exec_() self.eventLoop = None def updateSelected(self): layoutItem = self.grid.itemAt(0) i = 0 while layoutItem: w = layoutItem.widget() if w and isinstance(w, CColorPickerItem): if w != self.sender(): w.setSelected(False) i += 1 layoutItem = self.grid.itemAt(i) s = self.sender() if s and isinstance(s, CColorPickerItem): item = s self.lastSel = item.color() self.emit(SIGNAL('selected(QColor)'), item.color()) self.hide() def mouseReleaseEvent(self, e): if not self.rect().contains(e.pos()): self.hide() def keyPressEvent(self, e): curRow = 0 curCol = 0 foundFocus = False for j in xrange(self.grid.rowCount()): if foundFocus: break for i in xrange(self.grid.columnCount()): w = self.widgetAt.get(j, {}).get(i, None) if w and w.hasFocus(): curRow = j curCol = i foundFocus = True break if e.key() == Qt.Key_Left: if curCol > 0: curCol -= 1 elif curRow > 0: curRow -= 1 curCol = self.grid.columnCount() - 1 elif e.key() == Qt.Key_Right: if curCol < self.grid.columnCount() - 1 and self.widgetAt[curRow][ curCol + 1]: curCol += 1 elif curRow < self.grid.rowCount() - 1: curRow += 1 curCol = 0 elif e.key() == Qt.Key_Up: if curRow > 0: curRow -= 1 else: curCol = 0 elif e.key() == Qt.Key_Down: if curRow < self.grid.rowCount() - 1: w = self.widgetAt.get(curRow + 1, {}).get(curCol, None) if w: curRow += 1 else: for i in xrange(self.grid.columnCount()): if not self.widgetAt.get(curRow + 1, {}).get(i, None): curCol = i - 1 curRow += 1 elif e.key() in (Qt.Key_Space, Qt.Key_Return, Qt.Key_Enter): w = self.widgetAt.get(curRow, {}).get(curCol, None) if w and (isinstance(w, CColorPickerItem) or isinstance(w, QPushButton)): w.setSelected(True) layoutItem = self.grid.itemAt(0) i = 0 while layoutItem: wi = layoutItem.widget() if wi and isinstance(wi, CColorPickerItem): if wi != w: wi.setSelected(False) i += 1 layoutItem = self.grid.itemAt(i) self.lastSel = w.color() self.emit(SIGNAL('selected(QColor)'), w.color()) self.hide() elif e.key() == Qt.Key_Escape: self.hide() else: e.ignore() self.widgetAt.get(curRow, {}).get(curCol, None).setFocus() def hideEvent(self, e): if self.eventLoop: self.eventLoop.exit() self.setFocus() self.emit(SIGNAL('hid()')) QFrame.hideEvent(self, e) def lastSelected(self): return self.lastSel def showEvent(self, e): foundSelected = False for i in xrange(self.grid.columnCount()): for j in xrange(self.grid.rowCount()): w = self.widgetAt.get(j, {}).get(i, None) if isinstance(w, CColorPickerItem) and w.isSelected(): w.setFocus() foundSelected = True break if not foundSelected: if not self.items: self.setFocus() else: self.widgetAt.get(0, {}).get(0, None).setFocus() def regenerateGrid(self): self.widgetAt.clear() columns = self.cols if columns == -1: columns = ceil(sqrt(len(self.items))) if self.grid: sip.delete(self.grid) self.grid = QGridLayout(self) self.grid.setMargin(1) self.grid.setSpacing(0) ccol = 0 crow = 0 for i in xrange(len(self.items)): if self.items[i]: self.widgetAt.setdefault(crow, {})[ccol] = self.items[i] self.grid.addWidget(self.items[i], crow, ccol) ccol += 1 if ccol == columns: ccol = 0 crow += 1 if self.moreButton: self.grid.addWidget(self.moreButton, crow, ccol) self.widgetAt.setdefault(crow, {})[ccol] = self.moreButton self.updateGeometry() def getColorFromDialog(self): rgb, ok = QColorDialog.getRgba(self.lastSel.rgba(), self.parentWidget()) if not ok: return col = QColor.fromRgba(rgb) self.insertColor(col, self.tr("Custom"), -1) self.lastSel = col self.emit(SIGNAL("selected(QColor)"), col)