def render_image(self, rgbobj, dst_x, dst_y): """Render the image represented by (rgbobj) at dst_x, dst_y in the pixel space. *** internal method-- do not use *** """ self.logger.debug("redraw surface=%s" % (self.surface)) if self.surface is None: return self.logger.debug("drawing to surface") # Prepare array for rendering # TODO: what are options for high bit depth under Qt? data = rgbobj.get_array(self.rgb_order, dtype=np.uint8) (height, width) = data.shape[:2] daht, dawd, depth = data.shape self.logger.debug("data shape is %dx%dx%d" % (dawd, daht, depth)) # Get qimage for copying pixel data qimage = self._get_qimage(data) drawable = self.surface painter = QPainter(drawable) #painter.setWorldMatrixEnabled(True) # fill surface with background color size = drawable.size() sf_wd, sf_ht = size.width(), size.height() bg = self.viewer.img_bg bgclr = self._get_color(*bg) painter.fillRect(QtCore.QRect(0, 0, sf_wd, sf_ht), bgclr) # draw image data from buffer to offscreen pixmap painter.drawImage(QtCore.QRect(dst_x, dst_y, width, height), qimage, QtCore.QRect(0, 0, width, height))
def _render_offscreen(self, drawable, data, dst_x, dst_y, width, height): # NOTE [A] daht, dawd, depth = data.shape self.logger.debug("data shape is %dx%dx%d" % (dawd, daht, depth)) # Get qimage for copying pixel data qimage = self._get_qimage(data) painter = QtGui.QPainter(drawable) painter.setWorldMatrixEnabled(True) # fill pixmap with background color imgwin_wd, imgwin_ht = self.get_window_size() painter.fillRect(QtCore.QRect(0, 0, imgwin_wd, imgwin_ht), self.img_bg) # draw image data from buffer to offscreen pixmap painter.drawImage(QtCore.QRect(dst_x, dst_y, width, height), qimage, QtCore.QRect(0, 0, width, height)) # Draw a cross in the center of the window in debug mode if self.t_['show_pan_position']: clr = QtGui.QColor() clr.setRgbF(1.0, 0.0, 0.0) painter.setPen(clr) ctr_x, ctr_y = self.get_center() painter.drawLine(ctr_x - 10, ctr_y, ctr_x + 10, ctr_y) painter.drawLine(ctr_x, ctr_y - 10, ctr_x, ctr_y + 10) # render self.message if self.message: self.draw_message(painter, imgwin_wd, imgwin_ht, self.message)
def update_image(self): if (not self.pixmap) or (not self.imgwin): return if isinstance(self.renderer.surface, QPixmap): # optimization when Qt is used as the renderer: # if renderer surface is already an offscreen QPixmap # then we can update the window directly from it #self.pixmap = self.renderer.surface pass else: if isinstance(self.renderer.surface, QImage): # optimization when Qt is used as the renderer: # renderer surface is already a QImage qimage = self.renderer.surface else: # otherwise, get the render surface as an array and # convert to a QImage try: arr = self.renderer.get_surface_as_array(order='BGRA') qimage = self._get_qimage(arr, QImage.Format_RGB32) except Exception as e: self.logger.error("Error from renderer: %s" % (str(e))) return # copy image from renderer to offscreen pixmap painter = QPainter(self.pixmap) #painter.setWorldMatrixEnabled(True) # fill surface with background color size = self.pixmap.size() width, height = size.width(), size.height() # draw image data from buffer to offscreen pixmap painter.drawImage(QtCore.QRect(0, 0, width, height), qimage, QtCore.QRect(0, 0, width, height)) self.logger.debug("updating window from pixmap") if hasattr(self, 'scene'): imgwin_wd, imgwin_ht = self.get_window_size() self.scene.invalidate(0, 0, imgwin_wd, imgwin_ht, QtGui.QGraphicsScene.BackgroundLayer) else: self.imgwin.update()
def _render_offscreen(self, drawable, data, dst_x, dst_y, width, height): # NOTE [A] daht, dawd, depth = data.shape self.logger.debug("data shape is %dx%dx%d" % (dawd, daht, depth)) # Get qimage for copying pixel data qimage = self._get_qimage(data) painter = QPainter(drawable) painter.setWorldMatrixEnabled(True) # fill pixmap with background color imgwin_wd, imgwin_ht = self.get_window_size() bgclr = self._get_color(*self.img_bg) painter.fillRect(QtCore.QRect(0, 0, imgwin_wd, imgwin_ht), bgclr) # draw image data from buffer to offscreen pixmap painter.drawImage(QtCore.QRect(dst_x, dst_y, width, height), qimage, QtCore.QRect(0, 0, width, height))
def repaint(self, rect): x1, y1, x2, y2 = rect.getCoords() width = x2 - x1 height = y2 - y1 # redraw the screen from backing pixmap #print "copying pixmap to widget" painter = QtGui.QPainter(self) rect = QtCore.QRect(x1, y1, width, height) painter.drawPixmap(rect, self.pixmap, rect)
def drawBackground(self, painter, rect): """When an area of the window is exposed, we just copy out of the server-side, off-screen pixmap to that area. """ if not self.pixmap: return x1, y1, x2, y2 = rect.getCoords() width = x2 - x1 height = y2 - y1 # redraw the screen from backing pixmap rect = QtCore.QRect(x1, y1, width, height) painter.drawPixmap(rect, self.pixmap, rect)
def paintEvent(self, event): """When an area of the window is exposed, we just copy out of the server-side, off-screen pixmap to that area. """ if not self.pixmap: return rect = event.rect() x1, y1, x2, y2 = rect.getCoords() width = x2 - x1 height = y2 - y1 # redraw the screen from backing pixmap painter = QtGui.QPainter(self) rect = QtCore.QRect(x1, y1, width, height) painter.drawPixmap(rect, self.pixmap, rect)
def resize(self, dims): """Resize our drawing area to encompass a space defined by the given dimensions. """ width, height = dims[:2] self.logger.debug("renderer reconfigured to %dx%d" % (width, height)) if self.surface_type == 'qpixmap': self.surface = QPixmap(width, height) else: self.surface = QImage(width, height, self.qimg_fmt) # fill surface with background color; # this reduces unwanted garbage in the resizing window painter = QPainter(self.surface) size = self.surface.size() sf_wd, sf_ht = size.width(), size.height() bg = self.viewer.img_bg bgclr = self._get_color(*bg) painter.fillRect(QtCore.QRect(0, 0, sf_wd, sf_ht), bgclr)
def _draw(self, cr): width, height = self.get_size() #print "window size is %d,%d" % (width, height) x1 = 0 x2 = width clr_wd = width // 256 rem_px = x2 - (clr_wd * 256) if rem_px > 0: ival = 256 // rem_px else: ival = 0 clr_ht = height #print "clr is %dx%d width=%d rem=%d ival=%d" % ( # width, height, clr_wd, rem_px, ival) j = ival off = 0 range_pts = [] for i in xrange(256): wd = clr_wd if rem_px > 0: j -= 1 if j == 0: rem_px -= 1 j = ival wd += 1 x = off (r, g, b) = self.rgbmap.get_rgbval(i) color = QtGui.QColor(r, g, b) cr.fillRect(QtCore.QRect(x, 0, wd, clr_ht), color) # Draw range scale if we are supposed to if self.t_showrange and self._interval.has_key(i): pct = float(i) / 256.0 val = int(self.loval + pct * (self.hival - self.loval)) text = "%d" % (val) rect = cr.boundingRect(0, 0, 1000, 1000, 0, text) x1, y1, x2, y2 = rect.getCoords() _wd = x2 - x1 _ht = y2 - y1 _ht = 14 rx = x ry = _ht - 2 range_pts.append((rx, ry, text)) off += wd # draw range pen = cr.pen() cr.setFont(QtGui.QFont(self.t_font, pointSize=self.t_fontsize)) color = QtGui.QColor() color.setRgbF(0.0, 0.0, 0.0) pen.setColor(color) cr.setPen(pen) for (x, y, text) in range_pts: # tick cr.drawLine(x, 0, x, 2) # number cr.drawText(x, y, text)
def _draw(self, cr): width, height = self.get_size() #print "window size is %d,%d" % (width, height) x1 = 0; x2 = width clr_wd = width // 256 rem_px = x2 - (clr_wd * 256) if rem_px > 0: ival = 256 // rem_px else: ival = 0 clr_ht = height #print "clr is %dx%d width=%d rem=%d ival=%d" % ( # width, height, clr_wd, rem_px, ival) dist = self.rgbmap.get_dist() j = ival; off = 0 range_pts = [] for i in range(256): wd = clr_wd if rem_px > 0: j -= 1 if j == 0: rem_px -= 1 j = ival wd += 1 x = off (r, g, b) = self.rgbmap.get_rgbval(i) color = QColor(r, g, b) cr.fillRect(QtCore.QRect(x, 0, wd, clr_ht), color) # Draw range scale if we are supposed to if self.t_showrange and i in self._interval: #cb_pct = float(i) / 256.0 cb_pct = float(x) / width # get inverse of distribution function and calculate value # at this position rng_pct = dist.get_dist_pct(cb_pct) val = float(self.loval + (rng_pct * (self.hival - self.loval))) text = "%.4g" % (val) rect = cr.boundingRect(0, 0, 1000, 1000, 0, text) x1, y1, x2, y2 = rect.getCoords() _wd = x2 - x1 _ht = y2 - y1 # override? _ht = 14 rx = x ry = _ht - 2 range_pts.append((rx, ry, text)) off += wd # draw range pen = cr.pen() cr.setFont(QFont(self.t_font, pointSize=self.t_fontsize)) color = QColor() color.setRgbF(0.0, 0.0, 0.0) pen.setColor(color) cr.setPen(pen) for (x, y, text) in range_pts: # tick cr.drawLine(x, 0, x, 2) # number cr.drawText(x, y, text)