Beispiel #1
0
 def _draw_ndi():
     img_data = np.NINF * np.ones((2, 2))
     argb, alpha = pgfuncs.makeARGB(img_data,
                                    lut=self._lut,
                                    levels=self._lut_levels,
                                    )
     self._raw_image = pgfuncs.makeQImage(argb, alpha, transpose=False)
Beispiel #2
0
 def _draw_ndi():
     img_data = np.NINF * np.ones((2, 2))
     argb, alpha = pgfuncs.makeARGB(img_data,
                                    lut=self._lut,
                                    levels=self._lut_levels,
                                    )
     self._raw_image = pgfuncs.makeQImage(argb, alpha, transpose=False)
Beispiel #3
0
    def export(self, fileName=None, toBytes=False, copy=False):
        if fileName is None and not toBytes and not copy:
            if USE_PYSIDE:
                filter = ["*."+str(f)
                          for f in QtGui.QImageWriter.supportedImageFormats()]
            else:
                filter = ["*."+bytes(f).decode('utf-8')
                          for f in QtGui.QImageWriter.supportedImageFormats()]
            preferred = ['*.png', '*.tif', '*.jpg']
            for p in preferred[::-1]:
                if p in filter:
                    filter.remove(p)
                    filter.insert(0, p)
            self.fileSaveDialog(filter=filter)
            return

        targetRect = QtCore.QRect(
            0, 0, self.params['width'], self.params['height'])
        sourceRect = self.getSourceRect()

        #self.png = QtGui.QImage(targetRect.size(), QtGui.QImage.Format_ARGB32)
        # self.png.fill(pyqtgraph.mkColor(self.params['background']))
        w, h = self.params['width'], self.params['height']
        if w == 0 or h == 0:
            raise Exception(
                "Cannot export image with size=0 (requested export size is %dx%d)" % (w, h))
        bg = np.empty((int(self.params['width']), int(
            self.params['height']), 4), dtype=np.ubyte)
        color = self.params['background']
        bg[:, :, 0] = color.blue()
        bg[:, :, 1] = color.green()
        bg[:, :, 2] = color.red()
        bg[:, :, 3] = color.alpha()
        self.png = fn.makeQImage(bg, alpha=True)

        # set resolution of image:
        origTargetRect = self.getTargetRect()
        resolutionScale = targetRect.width() / origTargetRect.width()
        #self.png.setDotsPerMeterX(self.png.dotsPerMeterX() * resolutionScale)
        #self.png.setDotsPerMeterY(self.png.dotsPerMeterY() * resolutionScale)

        painter = QtGui.QPainter(self.png)
        #dtr = painter.deviceTransform()
        try:
            self.setExportMode(True, {
                               'antialias': self.params['antialias'], 'background': self.params['background'], 'painter': painter, 'resolutionScale': resolutionScale})
            painter.setRenderHint(
                QtGui.QPainter.Antialiasing, self.params['antialias'])
            self.getScene().render(painter, QtCore.QRectF(
                targetRect), QtCore.QRectF(sourceRect))
        finally:
            self.setExportMode(False)
        painter.end()

        if copy:
            QtGui.QApplication.clipboard().setImage(self.png)
        elif toBytes:
            return self.png
        else:
            self.png.save(fileName)
Beispiel #4
0
    def paintEvent(self, ev):
        if self.opts is None:
            return
        if self.image is None:
            argb, alpha = fn.makeARGB(self.opts[0], *self.opts[1],
                                      **self.opts[2])
            self.image = fn.makeQImage(argb, alpha)
            self.opts = ()
        #if self.pixmap is None:
        #self.pixmap = QtGui.QPixmap.fromImage(self.image)
        p = QtGui.QPainter(self)
        if self.scaled:
            rect = self.rect()
            ar = rect.width() / float(rect.height())
            imar = self.image.width() / float(self.image.height())
            if ar > imar:
                rect.setWidth(int(rect.width() * imar / ar))
            else:
                rect.setHeight(int(rect.height() * ar / imar))

            p.drawImage(rect, self.image)
        else:
            p.drawImage(QtCore.QPointF(), self.image)
        #p.drawPixmap(self.rect(), self.pixmap)
        p.end()
Beispiel #5
0
    def setImage(self, lut, colStart, colEnd, cmapInv):
        # takes in a piece of spectrogram and produces a pair of images
        if cmapInv:
            im, alpha = fn.makeARGB(self.spec,
                                    lut=lut,
                                    levels=[colEnd, colStart])
        else:
            im, alpha = fn.makeARGB(self.spec,
                                    lut=lut,
                                    levels=[colStart, colEnd])
        im1 = fn.makeQImage(im, alpha)
        if im1.size().width() == 0:
            print(
                "ERROR: button not shown, likely bad spectrogram coordinates")
            return

        # hardcode all image sizes
        if self.cluster:
            self.im1 = im1.scaled(200, 150)
        else:
            self.specReductionFact = im1.size().width() / 500
            self.im1 = im1.scaled(500, im1.size().height())

        # draw lines
        if not self.cluster:
            unbufStartAdj = self.unbufStart / self.specReductionFact
            unbufStopAdj = self.unbufStop / self.specReductionFact
            self.line1 = QLineF(unbufStartAdj, 0, unbufStartAdj,
                                im1.size().height())
            self.line2 = QLineF(unbufStopAdj, 0, unbufStopAdj,
                                im1.size().height())
Beispiel #6
0
 def getAtlas(self):
     if not self.atlasValid:
         self.buildAtlas()
     if self.atlas is None:
         if len(self.atlasData) == 0:
             return QtGui.QPixmap(0,0)
         img = fn.makeQImage(self.atlasData, copy=False, transpose=False)
         self.atlas = QtGui.QPixmap(img)
     return self.atlas
Beispiel #7
0
 def getAtlas(self):
     if not self.atlasValid:
         self.buildAtlas()
     if self.atlas is None:
         if len(self.atlasData) == 0:
             return QtGui.QPixmap(0,0)
         img = fn.makeQImage(self.atlasData, copy=False, transpose=False)
         self.atlas = QtGui.QPixmap(img)
     return self.atlas
Beispiel #8
0
 def render(self):
     prof = debug.Profiler('ImageItem.render', disabled=True)
     if self.image is None:
         return
     if callable(self.lut):
         lut = self.lut(self.image)
     else:
         lut = self.lut
         
     argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
     self.qimage = fn.makeQImage(argb, alpha)
     #self.pixmap = QtGui.QPixmap.fromImage(self.qimage)
     prof.finish()
Beispiel #9
0
 def render(self):
     prof = debug.Profiler('ImageItem.render', disabled=True)
     if self.image is None:
         return
     if isinstance(self.lut, collections.Callable):
         lut = self.lut(self.image)
     else:
         lut = self.lut
     #print lut.shape
     #print self.lut
         
     argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
     self.qimage = fn.makeQImage(argb, alpha)
     prof.finish()
Beispiel #10
0
    def render(self):
        prof = debug.Profiler('ImageItem.render', disabled=True)
        if self.image is None:
            return
        if isinstance(self.lut, collections.Callable):
            lut = self.lut(self.image)
        else:
            lut = self.lut
        #print lut.shape
        #print self.lut

        argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
        self.qimage = fn.makeQImage(argb, alpha)
        prof.finish()
Beispiel #11
0
    def render(self):
        prof = debug.Profiler('ImageItem.render', disabled=True)
        if self.image is None:
            return
        if callable(self.lut):
            lut = self.lut(self.image)
        else:
            lut = self.lut
        #print lut.shape
        #print self.lut

        argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
        self.qimage = fn.makeQImage(argb, alpha)
        #self.pixmap = QtGui.QPixmap.fromImage(self.qimage)
        prof.finish()
Beispiel #12
0
 def _create_image(self, img_data):
     """This is the new image handler in the render pipeline.
     
     Regenerates a completely new image, given the new img_data.
     
     """
     assert threading.current_thread().name == self._render_thread_name
     assert img_data.ndim == 2
     
     dlog("_create_image called and re-assigning raw image dimensions")
     with self._mutex:
         #self._raw_image_height is dictated by the widget height, but the
         #raw img width comes from the underlying data model...
         self._raw_image_width = img_data.shape[1]
         
         #only keep a record of those rows that have data...
         # - soemthing is backwards here... we should be able to have the
         #    real data instead of going backwards from img data.
         # - FIXME
         populated_row_filter = img_data[:, 0] != np.NINF
         populated_img_data = img_data[populated_row_filter, :]
         
         self._src_data = collections.deque(populated_img_data)
         
         argb, alpha = pgfuncs.makeARGB(img_data,
                                        lut=self._lut,
                                        levels=self._lut_levels,
                                        )
         tmp_img = pgfuncs.makeQImage(argb, alpha, transpose=False)
         
         # We now have a fully generated tmp_image. We need to prep the
         # doubled-up ring buffer by setting up two copies and initializing
         # our current frame pointer offset...
         self.__ring_buffer = np.vstack((tmp_img.data, tmp_img.data))
         dlog("ring buffer size set to %r" % (self.__ring_buffer.shape, ))
         self.__cur_buffer_row = self._raw_image_height
         
         #set our _qimage to point at the proper location in the ring buffer...
         self._point_raw_image_at_cur_offset()
         
         self._image_ready = True
Beispiel #13
0
 def _create_image(self, img_data):
     """This is the new image handler in the render pipeline.
     
     Regenerates a completely new image, given the new img_data.
     
     """
     assert threading.current_thread().name == self._render_thread_name
     assert img_data.ndim == 2
     
     dlog("_create_image called and re-assigning raw image dimensions")
     with self._mutex:
         #self._raw_image_height is dictated by the widget height, but the
         #raw img width comes from the underlying data model...
         self._raw_image_width = img_data.shape[1]
         
         #only keep a record of those rows that have data...
         # - soemthing is backwards here... we should be able to have the
         #    real data instead of going backwards from img data.
         # - FIXME
         populated_row_filter = img_data[:, 0] != np.NINF
         populated_img_data = img_data[populated_row_filter, :]
         
         self._src_data = collections.deque(populated_img_data)
         
         argb, alpha = pgfuncs.makeARGB(img_data,
                                        lut=self._lut,
                                        levels=self._lut_levels,
                                        )
         tmp_img = pgfuncs.makeQImage(argb, alpha, transpose=False)
         
         # We now have a fully generated tmp_image. We need to prep the
         # doubled-up ring buffer by setting up two copies and initializing
         # our current frame pointer offset...
         self.__ring_buffer = np.vstack((tmp_img.data, tmp_img.data))
         dlog("ring buffer size set to %r" % (self.__ring_buffer.shape, ))
         self.__cur_buffer_row = self._raw_image_height
         
         #set our _qimage to point at the proper location in the ring buffer...
         self._point_raw_image_at_cur_offset()
         
         self._image_ready = True
Beispiel #14
0
 def readQImage(self):
     """
     Read the current buffer pixels out as a QImage.
     """
     w = self.width()
     h = self.height()
     self.repaint()
     pixels = np.empty((h, w, 4), dtype=np.ubyte)
     pixels[:] = 128
     pixels[...,0] = 50
     pixels[...,3] = 255
     
     glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels)
     
     # swap B,R channels for Qt
     tmp = pixels[...,0].copy()
     pixels[...,0] = pixels[...,2]
     pixels[...,2] = tmp
     pixels = pixels[::-1] # flip vertical
     
     img = fn.makeQImage(pixels, transpose=False)
     return img
Beispiel #15
0
    def readQImage(self):
        """
        Read the current buffer pixels out as a QImage.
        """
        w = self.width()
        h = self.height()
        self.repaint()
        pixels = np.empty((h, w, 4), dtype=np.ubyte)
        pixels[:] = 128
        pixels[..., 0] = 50
        pixels[..., 3] = 255

        glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, pixels)

        # swap B,R channels for Qt
        tmp = pixels[..., 0].copy()
        pixels[..., 0] = pixels[..., 2]
        pixels[..., 2] = tmp
        pixels = pixels[::-1]  # flip vertical

        img = fn.makeQImage(pixels, transpose=False)
        return img
Beispiel #16
0
    def render(self):
        #The same as pyqtgraph's ImageItem.render, with the exception that the makeARGB function is slightly different

        profile = debug.Profiler()
        if self.image is None or self.image.size == 0:
            return
        if isinstance(self.lut, Callable):
            lut = self.lut(self.image)
        else:
            lut = self.lut

        if self.autoDownsample:
            # reduce dimensions of image based on screen resolution
            o = self.mapToDevice(QtCore.QPointF(0,0))
            x = self.mapToDevice(QtCore.QPointF(1,0))
            y = self.mapToDevice(QtCore.QPointF(0,1))
            w = Point(x-o).length()
            h = Point(y-o).length()
            if w == 0 or h == 0:
                self.qimage = None
                return
            xds = max(1, int(1.0 / w))
            yds = max(1, int(1.0 / h))
            axes = [1, 0] if self.axisOrder == 'row-major' else [0, 1]
            image = fn.downsample(self.image, xds, axis=axes[0])
            image = fn.downsample(image, yds, axis=axes[1])
            self._lastDownsample = (xds, yds)
        else:
            image = self.image

        # Assume images are in column-major order for backward compatibility
        # (most images are in row-major order)

        if self.axisOrder == 'col-major':
            image = image.transpose((1, 0, 2)[:image.ndim])

        argb, alpha = makeARGBwithNaNs(image, lut=lut, levels=self.levels)
        self.qimage = fn.makeQImage(argb, alpha, transpose=False)
Beispiel #17
0
    def produceARGB(self):
        try:
            if self._numQueuedImages > 1:
                return  # Skip this frame in order to catch up

            image, lut, levels, viewBounds, onlyRenderVisible = (
                self._image, self._lut, self._levels, self._viewBounds,
                self._onlyRenderVisible)

            if onlyRenderVisible:
                # Only render the part of the image that is visible
                originalImageShape = image.shape
                renderBounds = (math.floor(viewBounds[1][0]),
                                math.ceil(viewBounds[1][1]),
                                math.floor(viewBounds[0][0]),
                                math.ceil(viewBounds[0][1]))

                image = image[renderBounds[0]:renderBounds[1],
                              renderBounds[2]:renderBounds[3]]

            argb, alpha = fn.makeARGB(image, lut=lut, levels=levels)

            if onlyRenderVisible:
                argbFull = np.zeros((*originalImageShape, argb.shape[2]),
                                    dtype=argb.dtype)
                argbFull[renderBounds[0]:renderBounds[1],
                         renderBounds[2]:renderBounds[3]] = argb
            else:
                argbFull = argb

            qimage = fn.makeQImage(argbFull, alpha, transpose=False)
            self.qimageProduced.emit(qimage)
        finally:
            self._numQueuedImagesMutex.lock()
            self._numQueuedImages -= 1
            self._numQueuedImagesMutex.unlock()
Beispiel #18
0
 def paintEvent(self, ev):
     if self.opts is None:
         return
     if self.image is None:
         argb, alpha = fn.makeARGB(self.opts[0], *self.opts[1], **self.opts[2])
         self.image = fn.makeQImage(argb, alpha)
         self.opts = ()
     #if self.pixmap is None:
         #self.pixmap = QtGui.QPixmap.fromImage(self.image)
     p = QtGui.QPainter(self)
     if self.scaled:
         rect = self.rect()
         ar = rect.width() / float(rect.height())
         imar = self.image.width() / float(self.image.height())
         if ar > imar:
             rect.setWidth(int(rect.width() * imar/ar))
         else:
             rect.setHeight(int(rect.height() * ar/imar))
             
         p.drawImage(rect, self.image)
     else:
         p.drawImage(QtCore.QPointF(), self.image)
     #p.drawPixmap(self.rect(), self.pixmap)
     p.end()
Beispiel #19
0
 def setImage(self, img):
     self.image = fn.makeQImage(img)
     self.update()
    def render(self):
        # Convert data to QImage for display.

        profile = debug.Profiler()
        if self.image is None or self.image.size == 0:
            return
        if isinstance(self.lut, collections.Callable):
            lut = self.lut(self.image)
        else:
            lut = self.lut

        if self.logScale:
            image = self.image + 1
            with np.errstate(invalid="ignore"):
                image = image.astype(np.float)
                np.log(image, where=image >= 0, out=image)  # map to 0-255
        else:
            image = self.image

        if self.autoDownsample:
            # reduce dimensions of image based on screen resolution
            o = self.mapToDevice(QPointF(0, 0))
            x = self.mapToDevice(QPointF(1, 0))
            y = self.mapToDevice(QPointF(0, 1))
            w = Point(x - o).length()
            h = Point(y - o).length()
            if w == 0 or h == 0:
                self.qimage = None
                return
            xds = max(1, int(1.0 / w))
            yds = max(1, int(1.0 / h))
            axes = [1, 0] if self.axisOrder == "row-major" else [0, 1]
            image = fn.downsample(image, xds, axis=axes[0])
            image = fn.downsample(image, yds, axis=axes[1])
            self._lastDownsample = (xds, yds)
        else:
            pass

        # if the image data is a small int, then we can combine levels + lut
        # into a single lut for better performance
        levels = self.levels
        if levels is not None and levels.ndim == 1 and image.dtype in (
                np.ubyte, np.uint16):
            if self._effectiveLut is None:
                eflsize = 2**(image.itemsize * 8)
                ind = np.arange(eflsize)
                minlev, maxlev = levels
                levdiff = maxlev - minlev
                levdiff = 1 if levdiff == 0 else levdiff  # don't allow division by 0
                if lut is None:
                    efflut = fn.rescaleData(ind,
                                            scale=255.0 / levdiff,
                                            offset=minlev,
                                            dtype=np.ubyte)
                else:
                    lutdtype = np.min_scalar_type(lut.shape[0] - 1)
                    efflut = fn.rescaleData(ind,
                                            scale=(lut.shape[0] - 1) / levdiff,
                                            offset=minlev,
                                            dtype=lutdtype,
                                            clip=(0, lut.shape[0] - 1))
                    efflut = lut[efflut]

                self._effectiveLut = efflut
            lut = self._effectiveLut
            levels = None

        # Assume images are in column-major order for backward compatibility
        # (most images are in row-major order)

        if self.axisOrder == "col-major":
            image = image.transpose((1, 0, 2)[:image.ndim])

        if self.logScale:
            with np.errstate(invalid="ignore"):
                levels = np.log(np.add(levels, 1))
            levels[0] = np.nanmax([levels[0], 0])

        argb, alpha = fn.makeARGB(image, lut=lut, levels=levels)
        self.qimage = fn.makeQImage(argb, alpha, transpose=False)
Beispiel #21
0
    def export(self, fileName=None, toBytes=False, copy=False):
        if fileName is None and not toBytes and not copy:
            if USE_PYSIDE:
                filter = ["*." + str(f) for f in
                          QtGui.QImageWriter.supportedImageFormats()]
            else:
                filter = ["*." + bytes(f).decode('utf-8') for f in
                          QtGui.QImageWriter.supportedImageFormats()]
            preferred = ['*.png', '*.tif', '*.jpg']
            for p in preferred[::-1]:
                if p in filter:
                    filter.remove(p)
                    filter.insert(0, p)
            self.fileSaveDialog(filter=filter)
            return

        targetRect = QtCore.QRect(0, 0, self.params['width'],
                                  self.params['height'])
        sourceRect = self.getSourceRect()

        # self.png = QtGui.QImage(targetRect.size(), QtGui.QImage.Format_ARGB32)
        # self.png.fill(pyqtgraph.mkColor(self.params['background']))
        w, h = int(self.params['width']), int(self.params['height'])
        if w == 0 or h == 0:
            raise Exception(
                "Cannot export image with size=0 (requested export size is %dx%d)" % (
                w, h))
        bg = np.empty((int(self.params['width']), int(self.params['height']), 4),
                      dtype=np.ubyte)
        color = self.params['background']
        bg[:, :, 0] = color.blue()
        bg[:, :, 1] = color.green()
        bg[:, :, 2] = color.red()
        bg[:, :, 3] = color.alpha()
        self.png = fn.makeQImage(bg, alpha=True)

        ## set resolution of image:
        origTargetRect = self.getTargetRect()
        resolutionScale = targetRect.width() / origTargetRect.width()
        # self.png.setDotsPerMeterX(self.png.dotsPerMeterX() * resolutionScale)
        # self.png.setDotsPerMeterY(self.png.dotsPerMeterY() * resolutionScale)

        painter = QtGui.QPainter(self.png)
        # dtr = painter.deviceTransform()
        try:
            self.setExportMode(True, {'antialias': self.params['antialias'],
                                      'background': self.params['background'],
                                      'painter': painter,
                                      'resolutionScale': resolutionScale})
            painter.setRenderHint(QtGui.QPainter.Antialiasing,
                                  self.params['antialias'])
            self.getScene().render(painter, QtCore.QRectF(targetRect),
                                   QtCore.QRectF(sourceRect))
        finally:
            self.setExportMode(False)
        painter.end()

        if copy:
            QtGui.QApplication.clipboard().setImage(self.png)
        elif toBytes:
            return self.png
        else:
            self.png.save(fileName)
Beispiel #22
0
	def render(self):
		# Convert data to QImage for display.
		
		profile = debug.Profiler()
		if self.image is None or self.image.size == 0:
			return
		
		# Request a lookup table if this image has only one channel
		if self.image.ndim == 2 or self.image.shape[2] == 1:
			if isinstance(self.lut, collections.Callable):
				lut = self.lut(self.image)
			else:
				lut = self.lut
		else:
			lut = None

		if self.autoDownsample:
			# reduce dimensions of image based on screen resolution
			o = self.mapToDevice(QtCore.QPointF(0,0))
			x = self.mapToDevice(QtCore.QPointF(1,0))
			y = self.mapToDevice(QtCore.QPointF(0,1))
			w = Point(x-o).length()
			h = Point(y-o).length()
			if w == 0 or h == 0:
				self.qimage = None
				return
			xds = max(1, int(1.0 / w))
			yds = max(1, int(1.0 / h))
			axes = [1, 0] if self.axisOrder == 'row-major' else [0, 1]
			image = fn.downsample(self.image, xds, axis=axes[0])
			image = fn.downsample(image, yds, axis=axes[1])
			self._lastDownsample = (xds, yds)
		else:
			image = self.image

		# if the image data is a small int, then we can combine levels + lut
		# into a single lut for better performance
		levels = self.levels
		if levels is not None and levels.ndim == 1 and image.dtype in (np.ubyte, np.uint16):
			if self._effectiveLut is None:
				eflsize = 2**(image.itemsize*8)
				ind = np.arange(eflsize)
				minlev, maxlev = levels
				levdiff = maxlev - minlev
				levdiff = 1 if levdiff == 0 else levdiff  # don't allow division by 0
				if lut is None:
					efflut = fn.rescaleData(ind, scale=255./levdiff, 
											offset=minlev, dtype=np.ubyte)
				else:
					lutdtype = np.min_scalar_type(lut.shape[0]-1)
					efflut = fn.rescaleData(ind, scale=(lut.shape[0]-1)/levdiff,
											offset=minlev, dtype=lutdtype, clip=(0, lut.shape[0]-1))
					efflut = lut[efflut]
				
				self._effectiveLut = efflut
			lut = self._effectiveLut
			levels = None
		
		# Convert single-channel image to 2D array
		if image.ndim == 3 and image.shape[-1] == 1:
			image = image[..., 0]
		
		# Assume images are in column-major order for backward compatibility
		# (most images are in row-major order)
		if self.axisOrder == 'col-major':
			image = image.transpose((1, 0, 2)[:image.ndim])
		
		argb, alpha = fn.makeARGB(image, lut=lut, levels=levels)

		if self.alpha is not None:
			argb[:,:,3] = self.alpha.T

		self.qimage = fn.makeQImage(argb, True, transpose=False)
Beispiel #23
0
 def setImage(self, img):
     self.image = fn.makeQImage(img)
     self.update()
Beispiel #24
0
    def render(self):
        #The same as pyqtgraph's ImageItem.render, with the exception that the makeARGB function is slightly different

        profile = debug.Profiler()
        if self.image is None or self.image.size == 0:
            return
        if isinstance(self.lut, Callable):
            lut = self.lut(self.image)
        else:
            lut = self.lut

        if self.autoDownsample:
            # reduce dimensions of image based on screen resolution
            o = self.mapToDevice(QtCore.QPointF(0, 0))
            x = self.mapToDevice(QtCore.QPointF(1, 0))
            y = self.mapToDevice(QtCore.QPointF(0, 1))
            w = Point(x - o).length()
            h = Point(y - o).length()
            if w == 0 or h == 0:
                self.qimage = None
                return
            xds = max(1, int(1.0 / w))
            yds = max(1, int(1.0 / h))
            axes = [1, 0] if self.axisOrder == 'row-major' else [0, 1]
            image = fn.downsample(self.image, xds, axis=axes[0])
            image = fn.downsample(image, yds, axis=axes[1])
            self._lastDownsample = (xds, yds)
        else:
            image = self.image

        # if the image data is a small int, then we can combine levels + lut
        # into a single lut for better performance
        levels = self.levels
        if levels is not None and levels.ndim == 1 and image.dtype in (
                np.ubyte, np.uint16):
            if self._effectiveLut is None:
                eflsize = 2**(image.itemsize * 8)
                ind = np.arange(eflsize)
                minlev, maxlev = levels
                levdiff = maxlev - minlev
                levdiff = 1 if levdiff == 0 else levdiff  # don't allow division by 0
                if lut is None:
                    efflut = fn.rescaleData(ind,
                                            scale=255. / levdiff,
                                            offset=minlev,
                                            dtype=np.ubyte)
                else:
                    lutdtype = np.min_scalar_type(lut.shape[0] - 1)
                    efflut = fn.rescaleData(ind,
                                            scale=(lut.shape[0] - 1) / levdiff,
                                            offset=minlev,
                                            dtype=lutdtype,
                                            clip=(0, lut.shape[0] - 1))
                    efflut = lut[efflut]

                self._effectiveLut = efflut
            lut = self._effectiveLut
            levels = None

        # Assume images are in column-major order for backward compatibility
        # (most images are in row-major order)

        if self.axisOrder == 'col-major':
            image = image.transpose((1, 0, 2)[:image.ndim])

        argb, alpha = makeARGBwithNaNs(image, lut=lut, levels=levels)
        self.qimage = fn.makeQImage(argb, alpha, transpose=False)
Beispiel #25
0
    def export(self, fileName=None, toBytes=False, copy=False):
        # Can only export video from DaXView
        if self.daxview == None:
            return
        # Can only write to video
        if toBytes:
            return []

        # Get filename from user (the fileSaveDialog function calls export after finishing)
        if fileName is None:
            self.fileSaveDialog(filter=['*.mpeg', '*.mp4'])
            return
        if fileName.endswith('.mpeg') == False and fileName.endswith(
                '.mp4') == False:
            fileName = fileName + '.mpeg'
        # Get directory where video should go
        dirName = os.path.dirname(fileName)

        # Play entire sequence and store to temporary PNG files
        progress = QtGui.QProgressDialog('Exporting movie...', 'Abort', 0,
                                         int(self.daxview.data.shape[0] * 1.1))
        for i in range(self.daxview.data.shape[0]):
            # Set current frame
            self.daxview.setCurrentIndex(i)
            if i >= self.daxview.data.shape[0]:
                progress.setLabelText('Generating video...')
            # Export to png image
            targetRect = QtCore.QRect(0, 0, self.params['width'],
                                      self.params['height'])
            sourceRect = self.getSourceRect()

            #self.png = QtGui.QImage(targetRect.size(), QtGui.QImage.Format_ARGB32)
            #self.png.fill(pyqtgraph.mkColor(self.params['background']))
            w, h = self.params['width'], self.params['height']
            if w == 0 or h == 0:
                raise Exception(
                    "Cannot export image with size=0 (requested export size is %dx%d)"
                    % (w, h))
            bg = np.empty((self.params['width'], self.params['height'], 4),
                          dtype=np.ubyte)
            color = self.params['background']
            bg[:, :, 0] = color.blue()
            bg[:, :, 1] = color.green()
            bg[:, :, 2] = color.red()
            bg[:, :, 3] = color.alpha()
            self.png = fn.makeQImage(bg, alpha=False)

            ## set resolution of image:
            origTargetRect = self.getTargetRect()
            resolutionScale = targetRect.width() / origTargetRect.width()

            painter = QtGui.QPainter(self.png)
            #dtr = painter.deviceTransform()
            try:
                self.setExportMode(
                    True, {
                        'antialias': self.params['antialias'],
                        'background': self.params['background'],
                        'painter': painter,
                        'resolutionScale': resolutionScale
                    })
                painter.setRenderHint(QtGui.QPainter.Antialiasing,
                                      self.params['antialias'])
                self.getScene().render(painter, QtCore.QRectF(targetRect),
                                       QtCore.QRectF(sourceRect))
            finally:
                self.setExportMode(False)
            painter.end()
            # Send to png file
            pngFile = dirName + '/temp_' + '{:03d}'.format(i) + '.png'
            self.png.save(pngFile)
            progress.setValue(i)
            QtGui.QApplication.processEvents()
            if progress.wasCanceled():
                # Clean-up PNGs
                rmfiles = glob.glob('temp_*.png')
                for f in rmfiles:
                    os.remove(f)
                progress.close()
                return
        progress.close()

        # Convert PNGs to movie with FFMPEG
        if fileName.endswith('mpeg'):
            codec = 'mpeg2video'
        else:
            codec = 'libx264'
        sp.call([
            'ffmpeg', '-r',
            str(self.params.param('frame rate').value()), '-i',
            dirName + '/temp_%03d.png', '-b:v', '1000K', '-c:v', codec,
            '-vframes',
            str(self.daxview.data.shape[0]), '-y', fileName
        ])
        # Clean-up PNGs
        rmfiles = glob.glob(dirName + '/temp_*.png')
        for f in rmfiles:
            os.remove(f)
        return
    def export(self, fileName=None, toBytes=False, copy=False):

        if fileName is None and not toBytes and not copy:

            if USE_PYSIDE:
                filter = [
                    "*." + str(f)
                    for f in QtGui.QImageWriter.supportedImageFormats()
                ]

            else:
                filter = [
                    "*." + bytes(f).decode('utf-8')
                    for f in QtGui.QImageWriter.supportedImageFormats()
                ]
            preferred = ['*.png', '*.tif', '*.jpg']

            for p in preferred[::-1]:

                if p in filter:
                    filter.remove(p)
                    filter.insert(0, p)

            self.fileSaveDialog(filter=filter)
            return

        targetRect = QtCore.QRect(0, 0, self.params['width'],
                                  self.params['height'])
        sourceRect = self.getSourceRect()

        w, h = self.params['width'], self.params['height']

        if w == 0 or h == 0:
            raise Exception(
                "Cannot export image with size=0 (requested export size is %dx%d)"
                % (w, h))

        #BEFORE
        #bg = np.empty((self.params['width'], self.params['height'], 4), dtype=np.ubyte)

        #AFTER
        bgSize = ((int(self.params['width']), int(self.params['height']), 4))
        bg = np.empty(bgSize, dtype=np.ubyte)

        #... I have no idea why that fixes it, I just guessed around and googled for 3 hours until it worked.
        #https://groups.google.com/forum/?nomobile=true#!topic/pyqtgraph/4jiAPUpLpF4
        #Above link led me on the right track to fixing it but for some reason I also had to declare bgSize separately?

        color = self.params['background']
        bg[:, :, 0] = color.blue()
        bg[:, :, 1] = color.green()
        bg[:, :, 2] = color.red()
        bg[:, :, 3] = color.alpha()
        self.png = fn.makeQImage(bg, alpha=True)

        ## set resolution of image:
        origTargetRect = self.getTargetRect()
        resolutionScale = targetRect.width() / origTargetRect.width()

        painter = QtGui.QPainter(self.png)

        try:
            self.setExportMode(
                True, {
                    'antialias': self.params['antialias'],
                    'background': self.params['background'],
                    'painter': painter,
                    'resolutionScale': resolutionScale
                })
            painter.setRenderHint(QtGui.QPainter.Antialiasing,
                                  self.params['antialias'])
            self.getScene().render(painter, QtCore.QRectF(targetRect),
                                   QtCore.QRectF(sourceRect))

        finally:
            self.setExportMode(False)
        painter.end()

        if copy:
            QtGui.QApplication.clipboard().setImage(self.png)

        elif toBytes:
            return self.png

        else:
            self.png.save(fileName)