1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
import sys
import numpy as np
from .. import functions as fn
from ..parametertree import Parameter
from ..Qt import QtCore, QtGui, QtWidgets
from .Exporter import Exporter
translate = QtCore.QCoreApplication.translate
__all__ = ['ImageExporter']
class ImageExporter(Exporter):
Name = "Image File (PNG, TIF, JPG, ...)"
allowCopy = True
def __init__(self, item):
Exporter.__init__(self, item)
tr = self.getTargetRect()
if isinstance(item, QtWidgets.QGraphicsItem):
scene = item.scene()
else:
scene = item
bgbrush = scene.views()[0].backgroundBrush()
bg = bgbrush.color()
if bgbrush.style() == QtCore.Qt.BrushStyle.NoBrush:
bg.setAlpha(0)
self.params = Parameter.create(name='params', type='group', children=[
{
'name': 'width',
'title': translate("Exporter", 'width'),
'type': 'int',
'value': int(tr.width()),
'limits': (0, None)
},
{
'name': 'height',
'title': translate("Exporter", 'height'),
'type': 'int',
'value': int(tr.height()),
'limits': (0, None)
},
{
'name': 'antialias',
'title': translate("Exporter", 'antialias'),
'type': 'bool',
'value': True
},
{
'name': 'background',
'title': translate("Exporter", 'background'),
'type': 'color',
'value': bg
},
{
'name': 'invertValue',
'title': translate("Exporter", 'invertValue'),
'type': 'bool',
'value': False
}
])
self.params.param('width').sigValueChanged.connect(self.widthChanged)
self.params.param('height').sigValueChanged.connect(self.heightChanged)
def widthChanged(self):
sr = self.getSourceRect()
ar = float(sr.height()) / sr.width()
self.params.param('height').setValue(int(self.params['width'] * ar), blockSignal=self.heightChanged)
def heightChanged(self):
sr = self.getSourceRect()
ar = float(sr.width()) / sr.height()
self.params.param('width').setValue(int(self.params['height'] * ar), blockSignal=self.widthChanged)
def parameters(self):
return self.params
@staticmethod
def getSupportedImageFormats():
filter = ["*."+f.data().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)
return filter
def export(self, fileName=None, toBytes=False, copy=False):
if fileName is None and not toBytes and not copy:
filter = self.getSupportedImageFormats()
self.fileSaveDialog(filter=filter)
return
w = int(self.params['width'])
h = 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))
targetRect = QtCore.QRect(0, 0, w, h)
sourceRect = self.getSourceRect()
self.png = QtGui.QImage(w, h, QtGui.QImage.Format.Format_ARGB32)
self.png.fill(self.params['background'])
## 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.RenderHint.Antialiasing, self.params['antialias'])
self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))
finally:
self.setExportMode(False)
painter.end()
if self.params['invertValue']:
bg = fn.ndarray_from_qimage(self.png)
if sys.byteorder == 'little':
cv = slice(0, 3)
else:
cv = slice(1, 4)
mn = bg[...,cv].min(axis=2)
mx = bg[...,cv].max(axis=2)
d = (255 - mx) - mn
bg[...,cv] += d[...,np.newaxis]
if copy:
QtWidgets.QApplication.clipboard().setImage(self.png)
elif toBytes:
return self.png
else:
return self.png.save(fileName)
ImageExporter.register()
|