image_view.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2012, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 
33 from PIL import Image
34 
35 # HACK workaround for upstream pillow issue python-pillow/Pillow#400
36 import sys
37 from python_qt_binding import QT_BINDING_MODULES
38 if (
39  not QT_BINDING_MODULES['QtCore'].__name__.startswith('PyQt5') and
40  'PyQt5' in sys.modules
41 ):
42  sys.modules['PyQt5'] = None
43 from PIL.ImageQt import ImageQt
44 
45 from rqt_bag import TopicMessageView
46 from rqt_bag_plugins import image_helper
47 
48 from python_qt_binding.QtGui import QPixmap
49 from python_qt_binding.QtWidgets import QGraphicsScene, QGraphicsView
50 
51 
52 class ImageView(TopicMessageView):
53 
54  """
55  Popup image viewer
56  """
57  name = 'Image'
58 
59  def __init__(self, timeline, parent, topic):
60  super(ImageView, self).__init__(timeline, parent, topic)
61 
62  self._image = None
63  self._image_topic = None
64  self._image_stamp = None
65  self.quality = Image.NEAREST # quality hint for scaling
66 
67  # TODO put the image_topic and image_stamp on the picture or display them in some fashion
68  self._overlay_font_size = 14.0
69  self._overlay_indent = (4, 4)
70  self._overlay_color = (0.2, 0.2, 1.0)
71 
72  self._image_view = QGraphicsView(parent)
73  self._image_view.resizeEvent = self._resizeEvent
74  self._scene = QGraphicsScene()
75  self._image_view.setScene(self._scene)
76  parent.layout().addWidget(self._image_view)
77 
78  # MessageView implementation
79  def _resizeEvent(self, event):
80  # TODO make this smarter. currently there will be no scrollbar even if the
81  # timeline extends beyond the viewable area
82  self._scene.setSceneRect(
83  0, 0, self._image_view.size().width() - 2, self._image_view.size().height() - 2)
85 
86  def message_viewed(self, bag, msg_details):
87  """
88  refreshes the image
89  """
90  TopicMessageView.message_viewed(self, bag, msg_details)
91  topic, msg, t = msg_details[:3]
92  if not msg:
93  self.set_image(None, topic, 'no message')
94  else:
95  self.set_image(msg, topic, msg.header.stamp)
96 
97  def message_cleared(self):
98  TopicMessageView.message_cleared(self)
99  self.set_image(None, None, None)
100 
101  # End MessageView implementation
103  if self._image:
104  scale_factor = min(
105  float(self._image_view.size().width() - 2) / self._image.size[0],
106  float(self._image_view.size().height() - 2) / self._image.size[1])
107  resized_image = self._image.resize(
108  (int(scale_factor * self._image.size[0]),
109  int(scale_factor * self._image.size[1])),
110  self.quality)
111 
112  QtImage = ImageQt(resized_image)
113  pixmap = QPixmap.fromImage(QtImage)
114  self._scene.clear()
115  self._scene.addPixmap(pixmap)
116 
117  def set_image(self, image_msg, image_topic, image_stamp):
118  self._image_msg = image_msg
119  if image_msg:
120  self._image = image_helper.imgmsg_to_pil(image_msg)
121  else:
122  self._image = None
123  self._image_topic = image_topic
124  self._image_stamp = image_stamp
125  self.put_image_into_scene()
def set_image(self, image_msg, image_topic, image_stamp)
Definition: image_view.py:117
def __init__(self, timeline, parent, topic)
Definition: image_view.py:59
def message_viewed(self, bag, msg_details)
Definition: image_view.py:86


rqt_bag_plugins
Author(s): Dirk Thomas , Aaron Blasdel , Austin Hendrix , Tim Field
autogenerated on Fri Feb 19 2021 03:14:15