def qimage_from_array(arr: np.ndarray) -> QImage: """ Create and return an QImage from a (N, M, C) uint8 array where C is 3 for RGB and 4 for RGBA channels. Parameters ---------- arr: (N, M C) uint8 array Returns ------- image: QImage An QImage with size (M, N) in ARGB32 format format depending on `C`. """ h, w, c = arr.shape if c == 4: format = QImage.Format_ARGB32 elif c == 3: format = QImage.Format_RGB32 else: raise ValueError(f"Wrong number of channels (need 3 or 4, got {c}") channels = arr.transpose((2, 0, 1)) img = QImage(w, h, QImage.Format_ARGB32) img.fill(Qt.white) buffer = img.bits().asarray(w * h * 4) view = np.frombuffer(buffer, np.uint32).reshape((h, w)) if format == QImage.Format_ARGB32: view[:, :] = qrgba(*channels) elif format == QImage.Format_RGB32: view[:, :] = qrgb(*channels) return img
def test_pyqtgraph(self): fd, fname = tempfile.mkstemp('.png') os.close(fd) graph = pyqtgraph.PlotWidget() try: imgio.PngFormat.write(fname, graph) im = QImage(fname) self.assertLess((200, 200), (im.width(), im.height())) finally: os.unlink(fname)
def test_other(self): fd, fname = tempfile.mkstemp('.png') os.close(fd) sc = QGraphicsScene() sc.addItem(QGraphicsRectItem(0, 0, 3, 3)) try: imgio.PngFormat.write(fname, sc) im = QImage(fname) # writer adds 15*2 of empty space self.assertEqual((30+4, 30+4), (im.width(), im.height())) finally: os.unlink(fname)
def test_pyside(self): img = QImage(100, 100, QImage.Format_ARGB32) img.fill(Qt.green) p = QPainter(img) pix = QPixmap(10, 10) pix.fill(Qt.red) frgmt = QPainter.PixmapFragment.create( QPointF(25, 25), QRectF(0, 0, 10, 10), 5., 5., ) p.drawPixmapFragments(frgmt, 1, pix) p.end() self.assertEqual(QColor(img.pixel(10, 10)), QColor(Qt.red))
def __init__(self, path, parent, direction, fixedSize=250, scaleHeight=None, scaleWidth=None, compassRotation=0): super(GyroImage, self).__init__() self.setAlignment(Qt.AlignCenter) self.setFixedWidth(fixedSize) self.setFixedHeight(fixedSize) self.parent = parent self.compassImage = QImage(Config.icons['gyro']['compass']['path']).scaledToWidth(self.width()) if scaleWidth is not None: self.image = QImage(path).scaledToWidth(scaleWidth) elif scaleHeight is not None: self.image = QImage(path).scaledToHeight(scaleHeight) else: self.image = QImage(path) self.direction = direction self.compassRotation = compassRotation
def __init__(self, *args, image=QImage(), heading="", link=QUrl(), **kwargs): super().__init__(*args, **kwargs) self.__link = QUrl() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.__heading = QLabel() self.__content = QLabel() self.layout().addWidget(self.__heading) self.layout().addWidget(self.__content, 10, Qt.AlignCenter) self.__shadow = DropShadowFrame() self.__shadow.setWidget(self.__content) self.setImage(image) self.setHeading(heading) self.setLink(link)
def update_webcam_image(self): if not self.isVisible(): if self.cap is not None: self.cap.release() self.cap = None return if self.cap is None: # Try capture devices in LIFO order for dev in range(5, -1, -1): cap = self.cap = cv2.VideoCapture(dev) if cap.isOpened(): break cap = self.cap self.capture_button.setDisabled(not cap.isOpened()) success, frame = cap.read() if not cap.isOpened() or not success: self.Error.no_webcam() return else: self.Error.no_webcam.clear() if self.snapshot_flash > 0: np.clip(frame.astype(np.int16) + self.snapshot_flash, 0, 255, out=frame) self.snapshot_flash -= 15 image = QImage(frame if self.avatar_filter else self.bgr2rgb(frame), frame.shape[1], frame.shape[0], QImage.Format_RGB888) pix = QPixmap.fromImage(image).scaled( self.imageLabel.size(), Qt.KeepAspectRatio | Qt.FastTransformation) self.imageLabel.setPixmap(pix)
def pygame_loop(self): self.animation.loop() self.image = QImage(self.animation.surface.get_buffer().raw, self.animation.surface.get_width(), self.animation.surface.get_height(), QImage.Format_RGB32) # repaint Qt window self.update()
def qmacstyle_accent_color(style: QStyle): option = QStyleOptionButton() option.state |= (QStyle.State_Active | QStyle.State_Enabled | QStyle.State_Raised) option.features |= QStyleOptionButton.DefaultButton option.text = "" size = style.sizeFromContents(QStyle.CT_PushButton, option, QSize(20, 10), None) option.rect = QRect(0, 0, size.width(), size.height()) img = QImage(size.width(), size.height(), QImage.Format_ARGB32_Premultiplied) img.fill(Qt.transparent) painter = QPainter(img) try: style.drawControl(QStyle.CE_PushButton, option, painter, None) finally: painter.end() color = img.pixelColor(size.width() // 2, size.height() // 2) return color
def update_properties(self): ## Mostly copied from OWScatterPlotGraph if not self.plot(): return if not self.rect: x,y = self.axes() self.rect = self.plot().data_rect_for_axes(x,y) s = self.graph_transform().mapRect(self.rect).size().toSize() if not s.isValid(): return rx = s.width() ry = s.height() rx -= rx % self.granularity ry -= ry % self.granularity p = self.graph_transform().map(QPointF(0, 0)) - self.graph_transform().map(self.rect.topLeft()) p = p.toPoint() ox = p.x() oy = -p.y() if self.classifier.classVar.is_continuous: imagebmp = orangeom.potentialsBitmap(self.classifier, rx, ry, ox, oy, self.granularity, self.scale) palette = [qRgb(255.*i/255., 255.*i/255., 255-(255.*i/255.)) for i in range(255)] + [qRgb(255, 255, 255)] else: imagebmp, nShades = orangeom.potentialsBitmap(self.classifier, rx, ry, ox, oy, self.granularity, self.scale, self.spacing) palette = [] sortedClasses = get_variable_values_sorted(self.classifier.domain.classVar) for cls in self.classifier.classVar.values: color = self.plot().discPalette.getRGB(sortedClasses.index(cls)) towhite = [255-c for c in color] for s in range(nShades): si = 1-float(s)/nShades palette.append(qRgb(*tuple([color[i]+towhite[i]*si for i in (0, 1, 2)]))) palette.extend([qRgb(255, 255, 255) for i in range(256-len(palette))]) self.potentialsImage = QImage(imagebmp, rx, ry, QImage.Format_Indexed8) self.potentialsImage.setColorTable(palette) self.potentialsImage.setNumColors(256) self.pixmap_item.setPixmap(QPixmap.fromImage(self.potentialsImage)) self.pixmap_item.setPos(self.graph_transform().map(self.rect.bottomLeft()))
def paint_with_data(data): model.setItemData(index, data) opt = self.view.viewOptions() opt.rect = QRect(QPoint(0, 0), delegate.sizeHint(opt, index)) delegate.initStyleOption(opt, index) img = QImage(opt.rect.size(), QImage.Format_ARGB32_Premultiplied) p = QPainter(img) try: delegate.paint(p, opt, index) finally: p.end()
def update_frame(self): # read pixle values from camera _, frame = self.vc.read() balls = [None, None] if frame.size: # display image in orange widget image = QImage(frame[:, :, ::-1].copy(), frame.shape[1], frame.shape[0], QImage.Format_RGB888) pix = QPixmap.fromImage(image).scaled( self.image_label.size(), Qt.KeepAspectRatio | Qt.FastTransformation) self.image_label.setPixmap(pix) # Convert BGR to HSV hsv_image = cv.cvtColor(frame, cv.COLOR_BGR2HSV) # accumulated_mask = np.zeros(hsv_image.shape[:2], dtype='uint8') for index, (lower, upper) in enumerate(BOUNDARIES): mask = cv.inRange(hsv_image, lower, upper) size = self.remap(np.count_nonzero(mask), 0, mask.size, 0.2, 1) rgb_value = (cv.cvtColor( np.uint8([[cv.mean(hsv_image, mask)[:3]]]), cv.COLOR_HSV2RGB).flatten()) balls[index] = (tuple(rgb_value) if rgb_value.any() else None, size) # accumulated_mask = cv.bitwise_or(accumulated_mask, mask) dominant_colors = find_image_colors(hsv_image, image_processing_size=(100, 100)) # accumulated_mask = cv.bitwise_not(accumulated_mask) # res = cv.bitwise_and(frame, frame, mask=accumulated_mask) # print(res.reshape((res.shape[0] * res.shape[1], 3)).shape) # print(cv.mean(hsv_image, accumulated_mask)) # res = cv.resize(res, (100, 100), interpolation=cv.INTER_AREA) # if res.size: # # display image in orange widget # image = QImage(res[:, :, ::-1].copy(), res.shape[1], res.shape[0], QImage.Format_RGB888) # pix = QPixmap.fromImage(image).scaled(self.image_label.size(), Qt.KeepAspectRatio | Qt.FastTransformation) # self.image_label.setPixmap(pix) # res = res.reshape((res.shape[0] * res.shape[1], 3)) # res = res[~(res == 0).all(1)] # # # print(res) # # colors = find_image_colors(res, k=6, image_processing_size=(150, 150)) return dominant_colors, balls
def nextFrameSlot(self): t = int(round(time.time() * 1000)) ret, f = self.cap.read() f = cv2.cvtColor(f, cv2.COLOR_BGR2RGB) qFormat = QImage.Format_Indexed8 if len(f.shape) == 3: if f.shape[2] == 4: qFormat = QImage.Format_RGBA8888 else: qFormat = QImage.Format_RGB888 self.image = QImage(f, f.shape[1], f.shape[0], f.strides[0], qFormat) if self.fullScreenImage is not None: img = self.fullScreenImage.findChild(ImageLabel, "image") img.setPixmap( QPixmap.fromImage( self.image.scaledToHeight(img.height() * 0.95))) else: self._page.setPixmap( QPixmap.fromImage(self.image.scaledToHeight(Config.camHeight))) self._frameLabel.setText("FPS: " + str(int(1000 / (t - self._time)))) self._time = t
def paint_with_data_(data): paint_with_data(delegate, data, self.view.viewOptions()) model.setItemData(index, data) opt = self.view.viewOptions() size = delegate.sizeHint(opt, index).expandedTo(QSize(10, 10)) opt.rect = QRect(QPoint(0, 0), size) delegate.initStyleOption(opt, index) img = QImage(opt.rect.size(), QImage.Format_ARGB32_Premultiplied) p = QPainter(img) try: delegate.paint(p, opt, index) finally: p.end()
def __init__(self, *args): super(CamViewer, self).__init__() self._timer = QTimer() self._timer.timeout.connect(self.nextFrameSlot) self._frameRate = Config.camFrameRate self._image = QImage() self._cap = cv2.VideoCapture(*args) self._cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._image.width()) self._cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._image.height()) self._cap.set(cv2.CAP_PROP_FPS, Config.camFrameRate) self.layout = QVBoxLayout(self) self.setLayout(self.layout) self._isImageFullscreen = False self._fullScreenImage = None self._page = ImageLabel(self) self._page.setAlignment(Qt.AlignCenter) self._page.setMaximumHeight(Config.camHeight) self._page.mReleased.connect(self.fullscreen) self.layout.addWidget(self._page) self._frameLabel = QLabel() self._frameLabel.setAlignment(Qt.AlignCenter) self._time = int(round(time.time() * 1000)) self.layout.addWidget(self._frameLabel)
def render_as_png(self, filename): img = QImage(50, 50, QImage.Format_ARGB32) img.fill(Qt.transparent) painter = QPainter(img) painter.setRenderHint(QPainter.Antialiasing, 1) self.scene.render(painter, QRectF(0, 0, 50, 50), QRectF(-25, -25, 50, 50)) painter.end() img.save(filename)
def test_delegate(self): model = DistanceMatrixModel() matrix = np.array([[0.0, 0.1, 0.2], [0.1, 0.0, 0.1], [0.2, 0.1, 0.0]]) model.set_data(matrix) delegate = TableBorderItem() for row, col in product(range(model.rowCount()), range(model.columnCount())): index = model.index(row, col) option = QStyleOptionViewItem() size = delegate.sizeHint(option, index).expandedTo(QSize(30, 18)) delegate.initStyleOption(option, index) img = QImage(size, QImage.Format_ARGB32_Premultiplied) painter = QPainter(img) try: delegate.paint(painter, option, index) finally: painter.end()
def _column1(): if role == Qt.DecorationRole: continuous_palette = ContinuousPaletteGenerator(*var.colors) line = continuous_palette.getRGB(np.arange(0, 1, 1 / 256)) data = np.arange(0, 256, dtype=np.int8).reshape( (1, 256)).repeat(16, 0) img = QImage(data, 256, 16, QImage.Format_Indexed8) img.setColorCount(256) img.setColorTable([qRgb(*x) for x in line]) img.data = data return img if role == Qt.ToolTipRole: return "{} - {}".format(self._encode_color(var.colors[0]), self._encode_color(var.colors[1])) if role == ColorRole: return var.colors
def paint_with_data( delegate: QAbstractItemDelegate, data: Dict[int, Any], options: QStyleOptionViewItem = None ) -> None: model = create_model(1, 1) index = model.index(0, 0) model.setItemData(index, data) opt = QStyleOptionViewItem(options) if options is not None else QStyleOptionViewItem() size = delegate.sizeHint(opt, index).expandedTo(QSize(10, 10)) opt.rect = QRect(QPoint(0, 0), size) delegate.initStyleOption(opt, index) img = QImage(opt.rect.size(), QImage.Format_ARGB32_Premultiplied) p = QPainter(img) try: delegate.paint(p, opt, index) finally: p.end()
def qimage_indexed_from_array(arr: np.ndarray, colortable: Sequence[Sequence[int]]) -> QImage: arr = np.asarray(arr, dtype=np.uint8) h, w = arr.shape colortable = np.asarray(colortable, dtype=np.uint8) ncolors, nchannels = colortable.shape img = QImage(w, h, QImage.Format_Indexed8) img.setColorCount(ncolors) if nchannels == 4: qrgb_ = qrgba elif nchannels == 3: qrgb_ = qrgb else: raise ValueError for i, c in enumerate(colortable): img.setColor(i, qrgb_(*c)) if img.size().isEmpty(): return img buffer = img.bits().asarray(w * h) view = np.frombuffer(buffer, np.uint8).reshape((h, w)) view[:, :] = arr return img
def _column1(): if role == Qt.DecorationRole: continuous_palette = \ ContinuousPaletteGenerator(*desc.get_colors()) line = continuous_palette.getRGB(np.arange(0, 1, 1 / 256)) data = np.arange(0, 256, dtype=np.int8). \ reshape((1, 256)). \ repeat(16, 0) img = QImage(data, 256, 16, QImage.Format_Indexed8) img.setColorCount(256) img.setColorTable([qRgb(*x) for x in line]) img.data = data return img if role == Qt.ToolTipRole: colors = desc.get_colors() return f"{self._encode_color(colors[0])} " \ f"- {self._encode_color(colors[1])}" if role == ColorRole: return desc.get_colors() return None
def _column1(): if role == Qt.DecorationRole: continuous_palette = ContinuousPaletteGenerator(*var.colors) line = continuous_palette.getRGB(np.arange(0, 1, 1 / 256)) data = np.arange(0, 256, dtype=np.int8). \ reshape((1, 256)). \ repeat(16, 0) img = QImage(data, 256, 16, QImage.Format_Indexed8) img.setColorCount(256) img.setColorTable([qRgb(*x) for x in line]) img.data = data return img if role == Qt.ToolTipRole: return "{} - {}".format(self._encode_color(var.colors[0]), self._encode_color(var.colors[1])) if role == ColorRole: return var.colors
class CamViewer(QWidget): def __init__(self, *args): super(CamViewer, self).__init__() self._timer = QTimer() self._timer.timeout.connect(self.nextFrameSlot) self._frameRate = Config.camFrameRate self._image = QImage() self._cap = cv2.VideoCapture(*args) self._cap.set(cv2.CAP_PROP_FRAME_WIDTH, self._image.width()) self._cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self._image.height()) self._cap.set(cv2.CAP_PROP_FPS, Config.camFrameRate) self.layout = QVBoxLayout(self) self.setLayout(self.layout) self._isImageFullscreen = False self._fullScreenImage = None self._page = ImageLabel(self) self._page.setAlignment(Qt.AlignCenter) self._page.setMaximumHeight(Config.camHeight) self._page.mReleased.connect(self.fullscreen) self.layout.addWidget(self._page) self._frameLabel = QLabel() self._frameLabel.setAlignment(Qt.AlignCenter) self._time = int(round(time.time() * 1000)) self.layout.addWidget(self._frameLabel) def fullscreen(self): if not self.isImageFullscreen: cam = QMainWindow(self) panel = QWidget(cam) panel.layout = QHBoxLayout(panel) panel.setLayout(panel.layout) image = ImageLabel(panel) image.setAlignment(Qt.AlignCenter) image.setObjectName("image") image.mReleased.connect(cam.parent().fullscreen) image.setPixmap(QPixmap.fromImage(cam.parent().image)) panel.layout.addWidget(image) cam.setCentralWidget(panel) cam.showFullScreen() cam.parent().isImageFullscreen = True cam.parent().fullScreenImage = cam else: self.fullScreenImage.close() self.fullScreenImage = None self.isImageFullscreen = False def nextFrameSlot(self): t = int(round(time.time() * 1000)) ret, f = self.cap.read() f = cv2.cvtColor(f, cv2.COLOR_BGR2RGB) qFormat = QImage.Format_Indexed8 if len(f.shape) == 3: if f.shape[2] == 4: qFormat = QImage.Format_RGBA8888 else: qFormat = QImage.Format_RGB888 self.image = QImage(f, f.shape[1], f.shape[0], f.strides[0], qFormat) if self.fullScreenImage is not None: img = self.fullScreenImage.findChild(ImageLabel, "image") img.setPixmap( QPixmap.fromImage( self.image.scaledToHeight(img.height() * 0.95))) else: self._page.setPixmap( QPixmap.fromImage(self.image.scaledToHeight(Config.camHeight))) self._frameLabel.setText("FPS: " + str(int(1000 / (t - self._time)))) self._time = t def start(self): self.timer.start(1000.0 / self.frameRate) self._page.repaint() def stop(self): self.timer.stop() def deleteLater(self): self.cap.release() super(CamViewer, self).deleteLater() @property def frameRate(self): return self._frameRate @frameRate.setter def frameRate(self, value): if not isinstance(value, int): raise TypeError('Supplied frame rate is not of type (int): %s' % type(value).__name__) else: self._frameRate = value @property def cap(self): return self._cap @property def timer(self): return self._timer @property def image(self): return self._image @image.setter def image(self, value): if not isinstance(value, QImage): raise TypeError('Supplied value is not of type (QImage): %s' % type(value).__name__) else: self._image = value @property def isImageFullscreen(self): return self._isImageFullscreen @isImageFullscreen.setter def isImageFullscreen(self, value): if not isinstance(value, bool): raise TypeError('Supplied value is not of type (bool): %s' % type(value).__name__) else: self._isImageFullscreen = value @property def fullScreenImage(self): return self._fullScreenImage @fullScreenImage.setter def fullScreenImage(self, value): if not isinstance(value, QMainWindow) and not isinstance( value, type(None)): raise TypeError('Supplied value is not of type (QMainWindow): %s' % type(value).__name__) else: self._fullScreenImage = value @property def stopped(self): return self._stopped @stopped.setter def stopped(self, value): if not isinstance(value, bool): raise TypeError('Supplied value is not of type (bool): %s' % type(value).__name__) else: self._stopped = value
def redraw_markers_overlay_image(self, *args, new_image=False): if (not args and not self._drawing_args or self.lat_attr is None or self.lon_attr is None): return if args: self._drawing_args = args north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args lat = self.data.get_column_view(self.lat_attr)[0] lon = self.data.get_column_view(self.lon_attr)[0] visible = ((lat <= north) & (lat >= south) & (lon <= east) & (lon >= west)).nonzero()[0] is_js_path = len(visible) <= 500 self.evalJS(''' window.legend_colors = %s; window.legend_shapes = %s; window.legend_sizes = %s; legendControl.remove(); legendControl.addTo(map); ''' % (self._legend_colors, self._legend_shapes if is_js_path else [], self._legend_sizes)) if is_js_path: self.evalJS('clear_markers_overlay_image()') self._update_js_markers(visible) self._owwidget.disable_some_controls(False) return self.evalJS('clear_markers_js();') self._owwidget.disable_some_controls(True) np.random.shuffle(visible) selected = (self._selected_indices if self._selected_indices is not None else np.zeros(len(lat), dtype=bool)) N_POINTS_PER_ITER = 1000 cur = 0 im = QImage(self._overlay_image_path) if im.isNull() or self._prev_origin != origin or new_image: im = QImage(width, height, QImage.Format_ARGB32) im.fill(Qt.transparent) else: dx, dy = self._prev_map_pane_pos - map_pane_pos im = im.copy(dx, dy, width, height) self._prev_map_pane_pos = np.array(map_pane_pos) self._prev_origin = origin painter = QPainter(im) painter.setRenderHint(QPainter.Antialiasing, True) self.evalJS( 'clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0' ) self._image_token = image_token = np.random.random() n_iters = np.ceil(len(visible) / N_POINTS_PER_ITER) def add_points(): nonlocal cur, image_token if image_token != self._image_token: return batch = visible[cur:cur + N_POINTS_PER_ITER] batch_lat = lat[batch] batch_lon = lon[batch] batch_selected = selected[batch] x, y = self.Projection.latlon_to_easting_northing( batch_lat, batch_lon) x, y = self.Projection.easting_northing_to_pixel( x, y, zoom, origin, map_pane_pos) if self._jittering: x += (np.random.random(len(x)) - .5) * (self._jittering * width) y += (np.random.random(len(x)) - .5) * (self._jittering * height) colors = (self._colorgen.getRGB( self._scaled_color_values[batch]).tolist() if self._color_attr else repeat((0xff, 0, 0))) sizes = self._sizes[batch] if self._size_attr else repeat(10) zipped = zip(x, y, batch_selected, sizes, colors) sortkey, penkey, sizekey, brushkey = itemgetter( 2, 3, 4), itemgetter(2), itemgetter(3), itemgetter(4) for is_selected, points in groupby(sorted(zipped, key=sortkey), key=penkey): for size, points in groupby(points, key=sizekey): pensize, pencolor = ((3, Qt.green) if is_selected else (.7, QColor(0, 0, 0, self._opacity))) size *= self._size_coef if size < 5: pensize /= 3 size += pensize size2 = size / 2 painter.setPen(Qt.NoPen if size < 5 and not is_selected else QPen(QBrush(pencolor), pensize)) for color, points in groupby(points, key=brushkey): color = tuple(color) + (self._opacity, ) painter.setBrush(QBrush(QColor(*color))) for x, y, *_ in points: painter.drawEllipse(x - size2, y - size2, size, size) im.save(self._overlay_image_path, 'PNG') self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;'.format( self._overlay_image_path, np.random.random())) cur += N_POINTS_PER_ITER if cur < len(visible): QTimer.singleShot(10, add_points) self._owwidget.progressBarAdvance(100 / n_iters, None) else: self._owwidget.progressBarFinished(None) self._owwidget.progressBarFinished(None) self._owwidget.progressBarInit(None) QTimer.singleShot(10, add_points)
def redraw_markers_overlay_image(self, *args, new_image=False): if not args and not self._drawing_args or self.data is None: return if args: self._drawing_args = args north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args lat, lon = self._latlon_data.T visible = ((lat <= north) & (lat >= south) & (lon <= east) & (lon >= west)).nonzero()[0] in_subset = (np.in1d(self.data.ids, self._subset_ids) if self._subset_ids.size else np.tile(True, len(lon))) is_js_path = self.is_js_path = len(visible) < self.N_POINTS_PER_ITER self._update_legend(is_js_path) np.random.shuffle(visible) # Sort points in subset to be painted last visible = visible[np.lexsort((in_subset[visible],))] if is_js_path: self.evalJS('clear_markers_overlay_image()') self._update_js_markers(visible, in_subset[visible]) self._owwidget.disable_some_controls(False) return self.evalJS('clear_markers_js();') self._owwidget.disable_some_controls(True) selected = (self._selected_indices if self._selected_indices is not None else np.zeros(len(lat), dtype=bool)) cur = 0 im = QImage(self._overlay_image_path) if im.isNull() or self._prev_origin != origin or new_image: im = QImage(width, height, QImage.Format_ARGB32) im.fill(Qt.transparent) else: dx, dy = self._prev_map_pane_pos - map_pane_pos im = im.copy(dx, dy, width, height) self._prev_map_pane_pos = np.array(map_pane_pos) self._prev_origin = origin painter = QPainter(im) painter.setRenderHint(QPainter.Antialiasing, True) self.evalJS('clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0') self._image_token = image_token = np.random.random() n_iters = np.ceil(len(visible) / self.N_POINTS_PER_ITER) def add_points(): nonlocal cur, image_token if image_token != self._image_token: return batch = visible[cur:cur + self.N_POINTS_PER_ITER] batch_lat = lat[batch] batch_lon = lon[batch] x, y = self.Projection.latlon_to_easting_northing(batch_lat, batch_lon) x, y = self.Projection.easting_northing_to_pixel(x, y, zoom, origin, map_pane_pos) if self._jittering: dx, dy = self._jittering_offsets[batch].T x, y = x + dx, y + dy colors = (self._colorgen.getRGB(self._scaled_color_values[batch]).tolist() if self._color_attr else repeat((0xff, 0, 0))) sizes = self._size_coef * \ (self._sizes[batch] if self._size_attr else np.tile(10, len(batch))) opacity_subset, opacity_rest = self._opacity, int(.8 * self._opacity) for x, y, is_selected, size, color, _in_subset in \ zip(x, y, selected[batch], sizes, colors, in_subset[batch]): pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7) pensize2 *= self._size_coef selpensize2 *= self._size_coef size2 = size / 2 if is_selected: painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2)) painter.drawEllipse(x - size2 - selpensize2, y - size2 - selpensize2, size + selpensize2, size + selpensize2) color = QColor(*color) if _in_subset: color.setAlpha(opacity_subset) painter.setBrush(QBrush(color)) painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2)) else: color.setAlpha(opacity_rest) painter.setBrush(Qt.NoBrush) painter.setPen(QPen(QBrush(color.lighter(120)), 2 * pensize2)) painter.drawEllipse(x - size2 - pensize2, y - size2 - pensize2, size + pensize2, size + pensize2) im.save(self._overlay_image_path, 'PNG') self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;' .format(self.toFileURL(self._overlay_image_path), np.random.random())) cur += self.N_POINTS_PER_ITER if cur < len(visible): QTimer.singleShot(10, add_points) self._owwidget.progressBarAdvance(100 / n_iters, None) else: self._owwidget.progressBarFinished(None) self._owwidget.progressBarFinished(None) self._owwidget.progressBarInit(None) QTimer.singleShot(10, add_points)
class ProbabilitiesItem(orangeqt.PlotItem): """ Displays class probabilities in the background :param classifier: The classifier for which the probabilities are calculated :type classifier: orange.P2NN :param granularity: The size of individual cells :type granularity: int :param scale: The data scale factor :type scale: float :param spacing: The space between cells :param spacing: int :param rect: The rectangle into which to draw the probabilities. If unspecified, the entire plot is used. :type rect: QRectF """ def __init__(self, classifier, granularity, scale, spacing, rect=None): orangeqt.PlotItem.__init__(self) self.classifier = classifier self.rect = rect self.granularity = granularity self.scale = scale self.spacing = spacing self.pixmap_item = QGraphicsPixmapItem(self) self.set_in_background(True) self.setZValue(ProbabilitiesZValue) def update_properties(self): ## Mostly copied from OWScatterPlotGraph if not self.plot(): return if not self.rect: x,y = self.axes() self.rect = self.plot().data_rect_for_axes(x,y) s = self.graph_transform().mapRect(self.rect).size().toSize() if not s.isValid(): return rx = s.width() ry = s.height() rx -= rx % self.granularity ry -= ry % self.granularity p = self.graph_transform().map(QPointF(0, 0)) - self.graph_transform().map(self.rect.topLeft()) p = p.toPoint() ox = p.x() oy = -p.y() if self.classifier.classVar.is_continuous: imagebmp = orangeom.potentialsBitmap(self.classifier, rx, ry, ox, oy, self.granularity, self.scale) palette = [qRgb(255.*i/255., 255.*i/255., 255-(255.*i/255.)) for i in range(255)] + [qRgb(255, 255, 255)] else: imagebmp, nShades = orangeom.potentialsBitmap(self.classifier, rx, ry, ox, oy, self.granularity, self.scale, self.spacing) palette = [] sortedClasses = get_variable_values_sorted(self.classifier.domain.classVar) for cls in self.classifier.classVar.values: color = self.plot().discPalette.getRGB(sortedClasses.index(cls)) towhite = [255-c for c in color] for s in range(nShades): si = 1-float(s)/nShades palette.append(qRgb(*tuple([color[i]+towhite[i]*si for i in (0, 1, 2)]))) palette.extend([qRgb(255, 255, 255) for i in range(256-len(palette))]) self.potentialsImage = QImage(imagebmp, rx, ry, QImage.Format_Indexed8) self.potentialsImage.setColorTable(palette) self.potentialsImage.setNumColors(256) self.pixmap_item.setPixmap(QPixmap.fromImage(self.potentialsImage)) self.pixmap_item.setPos(self.graph_transform().map(self.rect.bottomLeft())) def data_rect(self): return self.rect if self.rect else QRectF()
def __transparent_png(self): # PyQt is stupid and does not increment reference count on bg w = h = 50 self.__bg = bg = b"\xff\xff\x00" * w * h * 4 return QImage(bg, w, h, QImage.Format_ARGB32)
def __transparent_png(self): # PyQt is stupid and does not increment reference count on bg self.__bg = bg = np.zeros((50, 50, 4), dtype=np.ubyte) return QImage(bg.ctypes.data, bg.shape[1], bg.shape[0], QtGui.QImage.Format_ARGB32)
def redraw_markers_overlay_image(self, *args, new_image=False): if not args and not self._drawing_args or self.data is None: return if args: self._drawing_args = args north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args lat, lon = self._latlon_data.T visible = ((lat <= north) & (lat >= south) & (lon <= east) & (lon >= west)).nonzero()[0] in_subset = (np.in1d(self.data.ids, self._subset_ids) if self._subset_ids.size else np.tile(True, len(lon))) is_js_path = self.is_js_path = len(visible) < self.N_POINTS_PER_ITER self._update_legend(is_js_path) np.random.shuffle(visible) # Sort points in subset to be painted last visible = visible[np.lexsort((in_subset[visible],))] if is_js_path: self.evalJS('clear_markers_overlay_image()') self._update_js_markers(visible, in_subset[visible]) self._owwidget.disable_some_controls(False) return self.evalJS('clear_markers_js();') self._owwidget.disable_some_controls(True) selected = (self._selected_indices if self._selected_indices is not None else np.zeros(len(lat), dtype=bool)) cur = 0 im = QImage(self._overlay_image_path) if im.isNull() or self._prev_origin != origin or new_image: im = QImage(width, height, QImage.Format_ARGB32) im.fill(Qt.transparent) else: dx, dy = self._prev_map_pane_pos - map_pane_pos im = im.copy(dx, dy, width, height) self._prev_map_pane_pos = np.array(map_pane_pos) self._prev_origin = origin painter = QPainter(im) painter.setRenderHint(QPainter.Antialiasing, True) self.evalJS('clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0') self._image_token = image_token = np.random.random() n_iters = np.ceil(len(visible) / self.N_POINTS_PER_ITER) def add_points(): nonlocal cur, image_token if image_token != self._image_token: return batch = visible[cur:cur + self.N_POINTS_PER_ITER] batch_lat = lat[batch] batch_lon = lon[batch] x, y = self.Projection.latlon_to_easting_northing(batch_lat, batch_lon) x, y = self.Projection.easting_northing_to_pixel(x, y, zoom, origin, map_pane_pos) if self._jittering: dx, dy = self._jittering_offsets[batch].T x, y = x + dx, y + dy colors = (self._colorgen.getRGB(self._scaled_color_values[batch]).tolist() if self._color_attr else repeat((0xff, 0, 0))) sizes = self._size_coef * \ (self._sizes[batch] if self._size_attr else np.tile(10, len(batch))) opacity_subset, opacity_rest = self._opacity, int(.8 * self._opacity) for x, y, is_selected, size, color, _in_subset in \ zip(x, y, selected[batch], sizes, colors, in_subset[batch]): pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7) pensize2 *= self._size_coef selpensize2 *= self._size_coef size2 = size / 2 if is_selected: painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2)) painter.drawEllipse(x - size2 - selpensize2, y - size2 - selpensize2, size + selpensize2, size + selpensize2) color = QColor(*color) if _in_subset: color.setAlpha(opacity_subset) painter.setBrush(QBrush(color)) painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2)) else: color.setAlpha(opacity_rest) painter.setBrush(Qt.NoBrush) painter.setPen(QPen(QBrush(color.lighter(120)), 2 * pensize2)) painter.drawEllipse(x - size2 - pensize2, y - size2 - pensize2, size + pensize2, size + pensize2) im.save(self._overlay_image_path, 'PNG') self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;' .format(self.toFileURL(self._overlay_image_path), np.random.random())) cur += self.N_POINTS_PER_ITER if cur < len(visible): QTimer.singleShot(10, add_points) self._owwidget.progressBarAdvance(100 / n_iters, None) else: self._owwidget.progressBarFinished(None) self._image_token = None self._owwidget.progressBarFinished(None) self._owwidget.progressBarInit(None) QTimer.singleShot(10, add_points)
def welcome_dialog_paged(self): # type: (CanvasMainWindow) -> None """ Show a modal multipaged welcome screen. """ dlg = PagedDialog( self, windowTitle=self.tr("Orange Data Mining"), ) dlg.setWindowModality(Qt.ApplicationModal) dlg.setAttribute(Qt.WA_DeleteOnClose) dlg.layout().setSizeConstraint(QVBoxLayout.SetFixedSize) dlg.setStyleSheet(""" TabView::item:selected { background: rgb(243, 171, 86); } """) main = FancyWelcomeScreen() spec = welcome_screen_specs() if spec.image: background = QImage(spec.image) else: background = QImage("canvas_icons:orange-start-background.png") main.setImage(background) if spec.css: main.setStyleSheet(spec.css) else: main.setStyleSheet( "StartItem { background-color: rgb(123, 164, 214) }") def decorate_icon(icon): return decorate_welcome_icon(icon, "#6dacb2") for i, item in zip(range(3), spec.items): main.setItemText(i, item.text) main.setItemToolTip(i, item.tooltip) main.setItemIcon(i, decorate_icon(QIcon(item.icon))) main.setItemActiveIcon(i, decorate_icon(QIcon(item.active_icon))) main.item(i).setProperty("path", item.path) main.setCurrentIndex(0) main.activated.connect(lambda: openselectedbutton.click()) PageWelcome = dlg.addPage(sc_icon("Welcome.svg"), "Welcome", main) examples_ = examples.workflows(config.default) items = [previewmodel.PreviewItem(path=t.abspath()) for t in examples_] model = previewmodel.PreviewModel(items=items) model.delayedScanUpdate() browser = previewbrowser.PreviewBrowser() browser.setModel(model) PageTemplates = dlg.addPage(sc_icon("Templates.svg"), "Templates", browser) browser.activated.connect(lambda: openselectedbutton.click()) recent = [ previewmodel.PreviewItem(name=item.title, path=item.path) for item in self.recent_schemes ] model = previewmodel.PreviewModel(items=recent) browser = previewbrowser.PreviewBrowser() browser.setModel(model) model.delayedScanUpdate() PageRecent = dlg.addPage(self.recent_action.icon(), "Recent", browser) browser.activated.connect(lambda: openselectedbutton.click()) dlg.setPageEnabled(PageRecent, model.rowCount() > 0) page = SingleLinkPage( image=QImage( resource_path("icons/getting-started-video-tutorials.png")), heading="Getting Started", link=QUrl("https://www.youtube.com/watch?v=3nMcI4Hxm7c"), ) page.setContentsMargins(25, 25, 25, 25) PageGetStarted = dlg.addPage( canvas_icons("YouTube.svg"), "Get Started", page, ) buttons = dlg.buttonBox() buttons.setVisible(True) buttons.setStandardButtons(QDialogButtonBox.Open | QDialogButtonBox.Cancel) # choose the selected workflow button openselectedbutton = buttons.button(QDialogButtonBox.Open) openselectedbutton.setText(self.tr("Open")) openselectedbutton.setToolTip("Open the selected workflow") openselectedbutton.setDefault(True) newbutton = QPushButton("New", toolTip="Create a new workflow") s = QShortcut(QKeySequence.New, newbutton) s.activated.connect(newbutton.click) buttons.addButton(newbutton, QDialogButtonBox.AcceptRole) openexisting = QPushButton("Open Existing\N{HORIZONTAL ELLIPSIS}", toolTip="Open an existing workflow file") s = QShortcut(QKeySequence.Open, dlg) s.activated.connect(openexisting.click) buttons.addButton(openexisting, QDialogButtonBox.AcceptRole) settings = QSettings() show_start_key = "startup/show-welcome-screen" show_start = QCheckBox("Show at startup", checked=settings.value(show_start_key, True, type=bool)) # Abusing ResetRole to push the check box to the left in all button # layouts. buttons.addButton(show_start, QDialogButtonBox.ResetRole) def update_show_at_startup(value): settings.setValue(show_start_key, value) show_start.toggled.connect(update_show_at_startup) def on_page_changed(index): if index == PageWelcome: openselectedbutton.setEnabled(True) elif index == PageTemplates: openselectedbutton.setEnabled(bool(examples)) elif index == PageRecent: openselectedbutton.setEnabled(bool(recent)) elif index == PageGetStarted: openselectedbutton.setEnabled(False) else: openselectedbutton.setEnabled(False) dlg.currentIndexChanged.connect(on_page_changed) def open_example_workflow(path): # open a workflow without filename/directory tracking. wf = self.new_scheme_from(path) if self.is_transient(): window = self else: window = self.create_new_window() window.show() window.raise_() window.activateWindow() window.set_new_scheme(wf) def open_url(url): return QDesktopServices.openUrl(QUrl(url)) def on_clicked(button): current = dlg.currentIndex() path = None open_workflow_file = None if current == PageWelcome: open_workflow_file = open_url elif current == PageTemplates: open_workflow_file = open_example_workflow elif current == PageRecent: open_workflow_file = self.open_scheme_file if button is openselectedbutton and \ current in {PageTemplates, PageRecent}: w = dlg.widget(current) assert isinstance(w, previewbrowser.PreviewBrowser) assert w.currentIndex() != -1 model = w.model() item = model.item(w.currentIndex()) path = item.path() elif button is openselectedbutton and current == PageWelcome: w = dlg.widget(current) assert isinstance(w, FancyWelcomeScreen) assert w.currentIndex() != -1 path = w.item(w.currentIndex()).property("path") if path is not None: open_workflow_file(path) dlg.accept() buttons.clicked.connect(on_clicked) def on_open_existing(): filedlg = self._open_workflow_dialog() filedlg.fileSelected.connect(self.open_scheme_file) filedlg.accepted.connect(dlg.accept) filedlg.exec() openexisting.clicked.connect(on_open_existing) def new_window(): if not self.is_transient(): self.new_workflow_window() dlg.accept() newbutton.clicked.connect(new_window) dlg.show()