Aluode/PerceptionLabPortable
0
1import sys2 3import numpy as np4 5from .. import functions as fn6from ..parametertree import Parameter7from ..Qt import QtCore, QtGui, QtWidgets8from .Exporter import Exporter9 10translate = QtCore.QCoreApplication.translate11__all__ = ['ImageExporter']12 13class ImageExporter(Exporter):14 Name = "Image File (PNG, TIF, JPG, ...)"15 allowCopy = True16 17 def __init__(self, item):18 Exporter.__init__(self, item)19 tr = self.getTargetRect()20 if isinstance(item, QtWidgets.QGraphicsItem):21 scene = item.scene()22 else:23 scene = item24 bgbrush = scene.views()[0].backgroundBrush()25 bg = bgbrush.color()26 if bgbrush.style() == QtCore.Qt.BrushStyle.NoBrush:27 bg.setAlpha(0)28 29 self.params = Parameter.create(name='params', type='group', children=[30 {31 'name': 'width',32 'title': translate("Exporter", 'width'),33 'type': 'int',34 'value': int(tr.width()),35 'limits': (0, None)36 },37 {38 'name': 'height',39 'title': translate("Exporter", 'height'),40 'type': 'int',41 'value': int(tr.height()),42 'limits': (0, None)43 },44 {45 'name': 'antialias',46 'title': translate("Exporter", 'antialias'),47 'type': 'bool',48 'value': True49 },50 {51 'name': 'background',52 'title': translate("Exporter", 'background'),53 'type': 'color',54 'value': bg55 },56 {57 'name': 'invertValue',58 'title': translate("Exporter", 'invertValue'),59 'type': 'bool',60 'value': False61 }62 ])63 self.params.param('width').sigValueChanged.connect(self.widthChanged)64 self.params.param('height').sigValueChanged.connect(self.heightChanged)65 66 def widthChanged(self):67 sr = self.getSourceRect()68 ar = float(sr.height()) / sr.width()69 self.params.param('height').setValue(int(self.params['width'] * ar), blockSignal=self.heightChanged)70 71 def heightChanged(self):72 sr = self.getSourceRect()73 ar = float(sr.width()) / sr.height()74 self.params.param('width').setValue(int(self.params['height'] * ar), blockSignal=self.widthChanged)75 76 def parameters(self):77 return self.params78 79 @staticmethod80 def getSupportedImageFormats():81 filter = ["*."+f.data().decode('utf-8') for f in QtGui.QImageWriter.supportedImageFormats()]82 preferred = ['*.png', '*.tif', '*.jpg']83 for p in preferred[::-1]:84 if p in filter:85 filter.remove(p)86 filter.insert(0, p)87 return filter 88 89 def export(self, fileName=None, toBytes=False, copy=False):90 if fileName is None and not toBytes and not copy:91 filter = self.getSupportedImageFormats()92 self.fileSaveDialog(filter=filter)93 return94 95 w = int(self.params['width'])96 h = int(self.params['height'])97 if w == 0 or h == 0:98 raise Exception("Cannot export image with size=0 (requested "99 "export size is %dx%d)" % (w, h))100 101 targetRect = QtCore.QRect(0, 0, w, h)102 sourceRect = self.getSourceRect()103 104 self.png = QtGui.QImage(w, h, QtGui.QImage.Format.Format_ARGB32)105 self.png.fill(self.params['background'])106 107 ## set resolution of image:108 origTargetRect = self.getTargetRect()109 resolutionScale = targetRect.width() / origTargetRect.width()110 #self.png.setDotsPerMeterX(self.png.dotsPerMeterX() * resolutionScale)111 #self.png.setDotsPerMeterY(self.png.dotsPerMeterY() * resolutionScale)112 113 painter = QtGui.QPainter(self.png)114 #dtr = painter.deviceTransform()115 try:116 self.setExportMode(True, {117 'antialias': self.params['antialias'],118 'background': self.params['background'],119 'painter': painter,120 'resolutionScale': resolutionScale})121 painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing, self.params['antialias'])122 self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))123 finally:124 self.setExportMode(False)125 painter.end()126 127 if self.params['invertValue']:128 bg = fn.ndarray_from_qimage(self.png)129 if sys.byteorder == 'little':130 cv = slice(0, 3)131 else:132 cv = slice(1, 4)133 mn = bg[...,cv].min(axis=2)134 mx = bg[...,cv].max(axis=2)135 d = (255 - mx) - mn136 bg[...,cv] += d[...,np.newaxis]137 138 if copy:139 QtWidgets.QApplication.clipboard().setImage(self.png)140 elif toBytes:141 return self.png142 else:143 return self.png.save(fileName)144 145ImageExporter.register()146 