def transform(self, img=None): if not self._geometry or not self.displaymode == DisplayMode.remesh: return super(EwaldCorrected, self).transform( img) # Do pixel space transform when not calibrated from camsaxs import remesh_bbox img, q_x, q_z = remesh_bbox.remesh(np.squeeze(img), self._geometry, reflection=False, alphai=None) # Build Quads shape = img.shape a = shape[-2] - 1, 0 # bottom-left b = shape[-2] - 1, shape[-1] - 1 # bottom-right c = 0, shape[-1] - 1 # top-right d = 0, 0 # top-left quad1 = QPolygonF() quad2 = QPolygonF() for p, q in zip([a, b, c, d], [a, b, c, d]): # the zip does the flip :P quad1.append(QPointF(*p[::-1])) quad2.append(QPointF(q_x[q], q_z[q])) transform = QTransform() QTransform.quadToQuad(quad1, quad2, transform) for item in self.view.items: if isinstance(item, ImageItem): item.setTransform(transform) self._transform = transform return img, self._transform
def setData(self, data): xvals = data.coords[data.dims[-1]] yvals = data.coords[data.dims[-2]] xmin = float(xvals.min()) xmax = float(xvals.max()) ymin = float(yvals.min()) ymax = float(yvals.max()) # Position the image according to coords shape = data.shape a = [(0, shape[-1]), (shape[-2] - 1, shape[-1]), (shape[-2] - 1, 1), (0, 1)] # b = [(ymin, xmax), (ymax, xmax), (ymax, xmin), (ymin, xmin)] b = [(xmax, ymin), (xmax, ymax), (xmin, ymax), (xmin, ymin)] quad1 = QPolygonF() quad2 = QPolygonF() for p, q in zip(a, b): quad1.append(QPointF(*p)) quad2.append(QPointF(*q)) transform = QTransform() QTransform.quadToQuad(quad1, quad2, transform) # Bind coords from the xarray to the timeline axis # super(SliceableGraphicsView, self).setImage(img, autoRange, autoLevels, levels, axes, np.asarray(img.coords[img.dims[0]]), pos, scale, transform, autoHistogramRange, levelMode) self.image_item.setImage(np.asarray(data), autoLevels=False) self.image_item.setTransform(transform) # Label the image axes self.view.setLabel('left', data.dims[-2]) self.view.setLabel('bottom', data.dims[-1])
def updatePosition(self, scene): # 1. Get pix coords for each lat/lon point pos0 = scene.posFromLonLat(self._lon0, self._lat0) pos1 = scene.posFromLonLat(self._lon1, self._lat1) pos2 = scene.posFromLonLat(self._lon2, self._lat2) pos3 = scene.posFromLonLat(self._lon3, self._lat3) self.prepareGeometryChange() # Set the image to 0, 0, then use a transform to # to translate, rotate and warp it to the map # tranfsorm and scale self.setPos(0, 0) t = QTransform() poly1 = QPolygonF() w = self.pixmap().width() h = self.pixmap().height() poly1.append(QPointF(0, 0)) poly1.append(QPointF(w, 0)) poly1.append(QPointF(w, h)) poly1.append(QPointF(0, h)) poly2 = QPolygonF() poly2.append(QPointF(pos0[0], pos0[1])) poly2.append(QPointF(pos1[0], pos1[1])) poly2.append(QPointF(pos2[0], pos2[1])) poly2.append(QPointF(pos3[0], pos3[1])) success = QTransform.quadToQuad(poly1, poly2, t) if not success: logging.error('Unable to register image') self.setTransform(t)
def setImage(self, img, **kwargs): if hasattr(img, 'coords'): if 'transform' not in kwargs: xvals = img.coords[img.dims[-2]] yvals = img.coords[img.dims[-1]] xmin = float(xvals.min()) xmax = float(xvals.max()) ymin = float(yvals.min()) ymax = float(yvals.max()) # Position the image according to coords shape = img.shape a = [(0, shape[-2]), (shape[-1] - 1, shape[-2]), (shape[-1] - 1, 1), (0, 1)] b = [(ymin, xmin), (ymax, xmin), (ymax, xmax), (ymin, xmax)] quad1 = QPolygonF() quad2 = QPolygonF() for p, q in zip(a, b): quad1.append(QPointF(*p)) quad2.append(QPointF(*q)) transform = QTransform() QTransform.quadToQuad(quad1, quad2, transform) kwargs['transform'] = transform if 'xvals' not in kwargs: kwargs['xvals'] = np.asarray(img.coords[img.dims[0]]) # Set the timeline axis label from dims self.ui.roiPlot.setLabel('bottom', img.dims[0]) # Label the image axes self.axesItem.setLabel('left', img.dims[-2]) self.axesItem.setLabel('bottom', img.dims[-1]) # Add a bit more size self.ui.roiPlot.setMinimumSize(QSize(0, 70)) # Bind coords from the xarray to the timeline axis super(XArrayView, self).setImage(img, **kwargs)
def qwtDrawDiamondSymbols(painter, points, numPoints, symbol): size = symbol.size() pen = QPen(symbol.pen()) pen.setJoinStyle(Qt.MiterJoin) painter.setPen(pen) painter.setBrush(symbol.brush()) for pos in points: x1 = pos.x() - 0.5 * size.width() y1 = pos.y() - 0.5 * size.height() x2 = x1 + size.width() y2 = y1 + size.height() polygon = QPolygonF() polygon.append(QPointF(pos.x(), y1)) polygon.append(QPointF(x1, pos.y())) polygon.append(QPointF(pos.x(), y2)) polygon.append(QPointF(x2, pos.y())) painter.drawPolygon(polygon)
def transform(self, img=None): # Build Quads shape = img.shape a = [(0, shape[-2] - 1), (shape[-1] - 1, shape[-2] - 1), (shape[-1] - 1, 0), (0, 0)] b = [(0, 1), (shape[-1] - 1, 1), (shape[-1] - 1, shape[-2]), (0, shape[-2])] quad1 = QPolygonF() quad2 = QPolygonF() for p, q in zip(a, b): quad1.append(QPointF(*p)) quad2.append(QPointF(*q)) transform = QTransform() QTransform.quadToQuad(quad1, quad2, transform) for item in self.view.items: if isinstance(item, ImageItem): item.setTransform(transform) self._transform = transform return img, transform
def paintEvent(self, event: QPaintEvent): painter = QPainter(self) painter.drawImage(self.rect(), self.image) if self.show_frame: painter.save() pen = QPen() pen.setWidth(2) pen.setColor(QColor("black")) painter.setPen(pen) rect = QRect(1, 1, self.width() - 2, self.height() - 2) painter.drawRect(rect) pen.setColor(QColor("white")) painter.setPen(pen) rect = QRect(3, 3, self.width() - 6, self.height() - 6) painter.drawRect(rect) painter.restore() if self.show_arrow: painter.save() triangle = QPolygonF() dist = 4 point1 = QPoint(self.width() - self.triangle_width, 0) size = QSize(20, self.height() // 2) rect = QRect(point1, size) painter.fillRect(rect, QColor("white")) triangle.append(point1 + QPoint(dist, dist)) triangle.append(point1 + QPoint(size.width() - dist, dist)) triangle.append(point1 + QPoint(size.width() // 2, size.height() - dist)) painter.setBrush(Qt.black) painter.drawPolygon(triangle, Qt.WindingFill) painter.restore()
def setData(self, data): # Constrain squareness when units match is_square = data.dims[-2].split('(')[-1] == data.dims[-1].split( '(')[-1] self.view.vb.setAspectLocked(is_square) xvals = data.coords[data.dims[-1]] yvals = data.coords[data.dims[-2]] xmin = float(xvals.min()) xmax = float(xvals.max()) ymin = float(yvals.min()) ymax = float(yvals.max()) # Position the image according to coords shape = data.shape a = [(0, shape[-2]), (shape[-1], shape[-2]), (shape[-1], 0), (0, 0)] # b = [(ymin, xmax), (ymax, xmax), (ymax, xmin), (ymin, xmin)] if self.slice_direction in ['horizontal', 'depth']: b = [(xmin, ymin), (xmax, ymin), (xmax, ymax), (xmin, ymax)] elif self.slice_direction == 'vertical': b = [(xmax, ymax), (xmin, ymax), (xmin, ymin), (xmax, ymin)] quad1 = QPolygonF() quad2 = QPolygonF() for p, q in zip(a, b): quad1.append(QPointF(*p)) quad2.append(QPointF(*q)) transform = QTransform() QTransform.quadToQuad(quad1, quad2, transform) # Bind coords from the xarray to the timeline axis # super(SliceableGraphicsView, self).setImage(img, autoRange, autoLevels, levels, axes, np.asarray(img.coords[img.dims[0]]), pos, scale, transform, autoHistogramRange, levelMode) self.image_item.setImage(np.asarray(data), autoLevels=False) self.image_item.setTransform(transform) # Label the image axes self.view.setLabel('left', data.dims[-2]) self.view.setLabel('bottom', data.dims[-1])
class MicroViewScene(QGraphicsScene): def __init__(self, parent): super().__init__(parent) self._imageItem = ImageGraphicsItem() self.addItem(self._imageItem) self._roiMode = False self._drawingRoi = False self.roiPen = QPen() self.roiPen.setWidthF(1.25) self.roiPen.setCosmetic(True) self.roiPen.setColor(Qt.yellow) self._roiPolygon = QPolygonF() self._roiItem = QGraphicsPolygonItem(self._roiPolygon) self._roiItem.setPen(self.roiPen) self.addItem(self._roiItem) def setImage(self, img): if isinstance(img, QImage): img = QPixmap.fromImage(img) self._imageItem.setPixmap(img) @Property(ImageGraphicsItem) def imageItem(self): return self._imageItem def enableRoiMode(self, enable): if enable == self._roiMode: return if enable: self._roiPolygon = QPolygonF() self._roiItem.setPolygon(self._roiPolygon) self._tempRoiPolygon = QPolygonF(self._roiPolygon) self._tempRoiPolygon.append(QPointF()) if not enable: self._roiItem.setPolygon(self._roiPolygon) self.roiChanged.emit(self._roiPolygon) self._roiMode = enable self.roiModeChanged.emit(enable) roiModeChanged = Signal(bool) @Property(bool, fset=enableRoiMode) def roiMode(self): return self._roiMode def setRoi(self, roi): if self._roiPolygon == roi: return self._roiPolygon = roi self._roiItem.setPolygon(self._roiPolygon) self.roiChanged.emit(roi) roiChanged = Signal(QPolygonF) @Property(QPolygonF, fset=setRoi, doc="Polygon describing the region of interest (ROI)") def roi(self): return self._roiPolygon def _appendPointToRoi(self, pos, polygon, replace_last=False): br = self._imageItem.boundingRect() topLeft = br.topLeft() bottomRight = br.bottomRight() # Make sure we stay inside the image boundaries xInBr = max(topLeft.x(), pos.x()) xInBr = min(bottomRight.x(), xInBr) yInBr = max(topLeft.y(), pos.y()) yInBr = min(bottomRight.y(), yInBr) pointInBr = QPointF(xInBr, yInBr) if replace_last: polygon[-1] = pointInBr else: polygon.append(pointInBr) def mousePressEvent(self, event): super().mousePressEvent(event) if not self._roiMode: return self._appendPointToRoi(event.scenePos(), self._roiPolygon, False) self._roiItem.setPolygon(self._roiPolygon) self._tempRoiPolygon = QPolygonF(self._roiPolygon) self._tempRoiPolygon.append(QPointF()) def mouseMoveEvent(self, event): super().mouseMoveEvent(event) if not self._roiMode: return self._appendPointToRoi(event.scenePos(), self._tempRoiPolygon, True) self._roiItem.setPolygon(self._tempRoiPolygon) def mouseDoubleClickEvent(self, event): super().mouseDoubleClickEvent(event) # the first click of the double click is a normal mousePressEvent, # thus the current point has already been added. Simply exit ROI mode self.roiMode = False
def create_high_dpi_drop_indicator_pixmap( self, size: QSizeF, area: DockWidgetArea, mode: OverlayMode) -> QPixmap: ''' Create high dpi drop indicator pixmap Parameters ---------- size : QSizeF area : DockWidgetArea mode : OverlayMode Returns ------- value : QPixmap ''' border_color = self.icon_color(IconColor.frame_color) background_color = self.icon_color(IconColor.window_background_color) window = self.public.window() # QT version compatibility (TODO necessary for qtpy?) device_pixel_ratio = (window.devicePixelRatioF() if hasattr(window, 'devicePixelRatioF') else window.devicePixelRatio()) pixmap_size = QSizeF(size * device_pixel_ratio) pm = QPixmap(pixmap_size.toSize()) pm.fill(QColor(0, 0, 0, 0)) p = QPainter(pm) pen = p.pen() shadow_rect = QRectF(pm.rect()) base_rect = QRectF() base_rect.setSize(shadow_rect.size() * 0.7) base_rect.moveCenter(shadow_rect.center()) # Fill shadow_color = self.icon_color(IconColor.shadow_color) if shadow_color.alpha() == 255: shadow_color.setAlpha(64) p.fillRect(shadow_rect, shadow_color) # Drop area rect. p.save() area_rect = QRectF() area_line = QLineF() non_area_rect = QRectF() if area == DockWidgetArea.top: area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width(), base_rect.height()*.5) non_area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5, base_rect.width(), base_rect.height()*.5) area_line = QLineF(area_rect.bottomLeft(), area_rect.bottomRight()) elif area == DockWidgetArea.right: area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(), base_rect.width()*.5, base_rect.height()) non_area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width()*.5, base_rect.height()) area_line = QLineF(area_rect.topLeft(), area_rect.bottomLeft()) elif area == DockWidgetArea.bottom: area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5, base_rect.width(), base_rect.height()*.5) non_area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width(), base_rect.height()*.5) area_line = QLineF(area_rect.topLeft(), area_rect.topRight()) elif area == DockWidgetArea.left: area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width()*.5, base_rect.height()) non_area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(), base_rect.width()*.5, base_rect.height()) area_line = QLineF(area_rect.topRight(), area_rect.bottomRight()) baseSize = base_rect.size() if (OverlayMode.container == mode and area != DockWidgetArea.center): base_rect = area_rect p.fillRect(base_rect, background_color) if area_rect.isValid(): pen = p.pen() pen.setColor(border_color) Color = self.icon_color(IconColor.overlay_color) if Color.alpha() == 255: Color.setAlpha(64) p.setBrush(Color) p.setPen(Qt.NoPen) p.drawRect(area_rect) pen = p.pen() pen.setWidth(1) pen.setColor(border_color) pen.setStyle(Qt.DashLine) p.setPen(pen) p.drawLine(area_line) p.restore() p.save() # Draw outer border pen = p.pen() pen.setColor(border_color) pen.setWidth(1) p.setBrush(Qt.NoBrush) p.setPen(pen) p.drawRect(base_rect) # draw window title bar p.setBrush(border_color) frame_rect = QRectF(base_rect.topLeft(), QSizeF(base_rect.width(), baseSize.height()/10)) p.drawRect(frame_rect) p.restore() # Draw arrow for outer container drop indicators if (OverlayMode.container == mode and area != DockWidgetArea.center): arrow_rect = QRectF() arrow_rect.setSize(baseSize) arrow_rect.setWidth(arrow_rect.width()/4.6) arrow_rect.setHeight(arrow_rect.height()/2) arrow_rect.moveCenter(QPointF(0, 0)) arrow = QPolygonF() arrow.append(arrow_rect.topLeft()) arrow.append(QPointF(arrow_rect.right(), arrow_rect.center().y())) arrow.append(arrow_rect.bottomLeft()) p.setPen(Qt.NoPen) p.setBrush(self.icon_color(IconColor.arrow_color)) p.setRenderHint(QPainter.Antialiasing, True) p.translate(non_area_rect.center().x(), non_area_rect.center().y()) if area == DockWidgetArea.top: p.rotate(-90) elif area == DockWidgetArea.right: ... elif area == DockWidgetArea.bottom: p.rotate(90) elif area == DockWidgetArea.left: p.rotate(180) p.drawPolygon(arrow) pm.setDevicePixelRatio(device_pixel_ratio) return pm
def paintEvent(self, event: QtGui.QPaintEvent): border_distance = 5 rect = self.rect() mid = rect.y() + rect.height() / 2 line_begin = QPointF(rect.height() + 10 + self.text_size.width(), mid) line_end = QPointF(rect.width() + rect.x() - 5, mid) triangle = QPolygonF() side_length = rect.height() - 2 * border_distance triangle_height = side_length * sqrt(3) / 2 start_point = QPointF(rect.x() + border_distance, rect.y() + border_distance) if self.isChecked(): triangle.append(start_point) triangle.append(start_point + QPointF(0, side_length)) triangle.append(start_point + QPointF(triangle_height, side_length / 2)) else: triangle.append(start_point) triangle.append(start_point + QPointF(side_length, 0)) triangle.append(start_point + QPointF(side_length / 2, triangle_height)) painter = QPainter(self) painter.setBrush(Qt.black) top = rect.height() - (self.text_size.height() / 2) painter.drawText(rect.height() + 5, top, self.info_text) painter.drawPolygon(triangle, Qt.WindingFill) painter.drawLine(QLineF(line_begin, line_end))