class ImageView(TopicMessageView): """ Popup image viewer """ name = 'Image' def __init__(self, timeline, parent, topic): super(ImageView, self).__init__(timeline, parent, topic) self._image = None self._image_topic = None self._image_stamp = None self.quality = Image.NEAREST # quality hint for scaling # TODO put the image_topic and image_stamp on the picture or display them in some fashion self._overlay_font_size = 14.0 self._overlay_indent = (4, 4) self._overlay_color = (0.2, 0.2, 1.0) self._image_view = QGraphicsView(parent) self._image_view.resizeEvent = self._resizeEvent self._scene = QGraphicsScene() self._image_view.setScene(self._scene) parent.layout().addWidget(self._image_view) # MessageView implementation def _resizeEvent(self, event): # TODO make this smarter. currently there will be no scrollbar even if the timeline extends beyond the viewable area self._scene.setSceneRect(0, 0, self._image_view.size().width() - 2, self._image_view.size().height() - 2) self.put_image_into_scene() def message_viewed(self, bag, msg_details): """ refreshes the image """ TopicMessageView.message_viewed(self, bag, msg_details) topic, msg, t = msg_details[:3] if not msg: self.set_image(None, topic, 'no message') else: self.set_image(msg, topic, msg.header.stamp) def message_cleared(self): TopicMessageView.message_cleared(self) self.set_image(None, None, None) # End MessageView implementation def put_image_into_scene(self): if self._image: resized_image = self._image.resize((self._image_view.size().width() - 2, self._image_view.size().height() - 2), self.quality) QtImage = ImageQt(resized_image) pixmap = QPixmap.fromImage(QtImage) self._scene.clear() self._scene.addPixmap(pixmap) def set_image(self, image_msg, image_topic, image_stamp): self._image_msg = image_msg if image_msg: self._image = image_helper.imgmsg_to_pil(image_msg) else: self._image = None self._image_topic = image_topic self._image_stamp = image_stamp self.put_image_into_scene()
class SandtrayView(TopicMessageView): name = 'Sandtray' def __init__(self, timeline, parent, topics): super(SandtrayView, self).__init__(timeline, parent, topics[0]) self._items = {} self._image = None self._image_topic = None self._image_stamp = None self.quality = Image.NEAREST # quality hint for scaling self._sandtray = SandtrayItem() self._sandtray_view = QGraphicsView(parent) self._sandtray_view.resizeEvent = self._resizeEvent self._scene = QGraphicsScene() self._scene.addItem(self._sandtray) self._sandtray_view.setScene(self._scene) self._sandtray_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio) parent.layout().addWidget(self._sandtray_view) # MessageView implementation def _resizeEvent(self, event): self._sandtray_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio) def message_viewed(self, bag, msg_details): """ render the sandtray """ TopicMessageView.message_viewed(self, bag, msg_details) topic, msg, t = msg_details[:3] if msg: if topic == "/zones": self._sandtray.update_zones(self._get_zones(msg)) else: for t in msg.transforms: if t.header.frame_id == "sandtray": self._items[t.child_frame_id] = t.transform.translation.x, -t.transform.translation.y self._sandtray.update(self._items) def message_cleared(self): TopicMessageView.message_cleared(self) self.set_image(None, None, None) # End MessageView implementation def _get_zones(self, msg): zones = {} for marker in msg.markers: polygon = [] color = QColor(255*marker.color.r, 255*marker.color.g, 255*marker.color.b, 255*marker.color.a) for p in marker.points: polygon.append(QPointF(p.x * SandtrayItem.scale, -p.y * SandtrayItem.scale)) zones.setdefault(color, []).append(polygon) return zones def put_image_into_scene(self): if self._image: QtImage = ImageQt(self._image) pixmap = QPixmap.fromImage(QtImage) self._scene.clear() self._scene.addPixmap(pixmap) def set_image(self, image_msg, image_topic, image_stamp): self._image_msg = image_msg if image_msg: self._image = image_helper.imgmsg_to_pil(image_msg) else: self._image = None self._image_topic = image_topic self._image_stamp = image_stamp self.put_image_into_scene()
class ImageView(TopicMessageView): """ Popup image viewer """ name = 'Image' def __init__(self, timeline, parent, topics): super(ImageView, self).__init__(timeline, parent, topics[0]) self._image = None self._image_topic = None self._image_stamp = None self.quality = Image.NEAREST # quality hint for scaling # TODO put the image_topic and image_stamp on the picture or display them in some fashion self._overlay_font_size = 14.0 self._overlay_indent = (4, 4) self._overlay_color = (0.2, 0.2, 1.0) self._image_view = QGraphicsView(parent) self._image_view.resizeEvent = self._resizeEvent self._scene = QGraphicsScene() self._image_view.setScene(self._scene) self._image_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio) parent.layout().addWidget(self._image_view) # MessageView implementation def _resizeEvent(self, event): self._image_view.fitInView(self._scene.itemsBoundingRect(), Qt.KeepAspectRatio) def message_viewed(self, bag, msg_details): """ refreshes the image """ TopicMessageView.message_viewed(self, bag, msg_details) topic, msg, t = msg_details[:3] if not msg: self.set_image(None, topic, 'no message') else: self.set_image(msg, topic, msg.header.stamp) def message_cleared(self): TopicMessageView.message_cleared(self) self.set_image(None, None, None) # End MessageView implementation def put_image_into_scene(self): if self._image: QtImage = ImageQt(self._image) pixmap = QPixmap.fromImage(QtImage) self._scene.clear() self._scene.addPixmap(pixmap) def set_image(self, image_msg, image_topic, image_stamp): self._image_msg = image_msg if image_msg: self._image = image_helper.imgmsg_to_pil(image_msg) else: self._image = None self._image_topic = image_topic self._image_stamp = image_stamp self.put_image_into_scene()