Skip to content

Commit

Permalink
Add dpi to saved PNGs, and scale images in reports
Browse files Browse the repository at this point in the history
  • Loading branch information
janezd committed Apr 21, 2023
1 parent b0f3206 commit 57416ff
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
37 changes: 24 additions & 13 deletions orangewidget/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ def save_pyqtgraph():
exporter = cls._get_exporter()
scene = object.scene()
if scene is None:
cls._export(exporter(scene), filename)
return
return cls._export(exporter(scene), filename)
views = scene.views()
if views:
# preserve scene rect and background brush
Expand All @@ -141,22 +140,21 @@ def save_pyqtgraph():
view = scene.views()[0]
scene.setSceneRect(view.sceneRect())
scene.setBackgroundBrush(effective_background(scene, view))
cls._export(exporter(scene), filename)
return cls._export(exporter(scene), filename)
finally:
# reset scene rect and background brush
scene.setBackgroundBrush(backgroundbrush)
scene.setSceneRect(scenerect)
else:
cls._export(exporter(scene), filename)
return cls._export(exporter(scene), filename)

def save_scene():
assert isinstance(object, QGraphicsScene)
ratio = get_scene_pixel_ratio(object)
views = object.views()
if not views:
rect = object.itemsBoundingRect()
_render(rect, ratio, rect.size(), object)
return
return _render(rect, ratio, rect.size(), object)

# Pick the first view. If there's a widget with multiple views that
# cares which one is used, it must set graph_name to view, not scene
Expand All @@ -166,11 +164,11 @@ def save_scene():
source_rect = QRect(
int(target_rect.x()), int(target_rect.y()),
int(target_rect.width()), int(target_rect.height()))
_render(source_rect, ratio, target_rect.size(), view)
return _render(source_rect, ratio, target_rect.size(), view)

def save_widget():
assert isinstance(object, QWidget)
_render(object.rect(), object.devicePixelRatio(), object.size(),
return _render(object.rect(), object.devicePixelRatio(), object.size(),
object)

def _render(
Expand Down Expand Up @@ -203,13 +201,16 @@ def _render(
# not a core dump
painter.end()
cls._save_buffer(buffer, filename)
return dict(width=buffer.size().width(),
height=buffer.size().height(),
pixel_ratio=pixel_ratio)

if isinstance(object, GraphicsItem):
save_pyqtgraph()
return save_pyqtgraph()
elif isinstance(object, QGraphicsScene):
save_scene()
return save_scene()
elif isinstance(object, QWidget): # this includes QGraphicsView
save_widget()
return save_widget()
else:
raise TypeError(f"{cls.__name__} "
f"cannot imagine {type(object).__name__}")
Expand All @@ -218,7 +219,7 @@ def _render(
def write(cls, filename, scene):
if type(scene) == dict:
scene = scene['scene']
cls.write_image(filename, scene)
return cls.write_image(filename, scene)

@classproperty
def img_writers(cls): # type: () -> Mapping[str, Type[ImgFormat]]
Expand Down Expand Up @@ -260,7 +261,11 @@ def _setup_painter(cls, painter, object, source_rect, buffer):

@staticmethod
def _save_buffer(buffer, filename):
buffer.save(filename, "png")
image = buffer.toImage()
dpm = 2835 * image.devicePixelRatio()
image.setDotsPerMeterX(dpm)
image.setDotsPerMeterY(dpm)
image.save(filename, "png")

@staticmethod
def _get_exporter():
Expand Down Expand Up @@ -300,6 +305,9 @@ def export(self, fileName=None, toBytes=False, copy=False):
QtGui.QImage.Format.Format_ARGB32)
self.png.fill(self.params['background'])
self.png.setDevicePixelRatio(self.ratio)
dpm = 2835 * self.ratio
self.png.setDotsPerMeterX(dpm)
self.png.setDotsPerMeterY(dpm)

## set resolution of image:
origTargetRect = self.getTargetRect()
Expand Down Expand Up @@ -348,6 +356,9 @@ def export(self, fileName=None, toBytes=False, copy=False):
def _export(exporter, filename):
buffer = exporter.export(toBytes=True)
buffer.save(filename, "png")
return dict(width=buffer.size().width(),
height=buffer.size().height(),
pixel_ratio=buffer.devicePixelRatio())


class ClipboardFormat(PngFormat):
Expand Down
16 changes: 10 additions & 6 deletions orangewidget/report/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,13 +627,17 @@ def get_html_img(
byte_array = QByteArray()
filename = QBuffer(byte_array)
filename.open(QIODevice.WriteOnly)
PngFormat.write(filename, scene)
img_data = PngFormat.write(filename, scene)

img_encoded = byte_array.toBase64().data().decode("utf-8")
return '<img {} src="data:image/png;base64,{}"/>'.format(
("" if max_height is None
else 'style="max-height: {}px"'.format(max_height)),
img_encoded
)

style_opts = []
if max_height is not None:
style_opts.append(f"max-height: {max_height}px")
if img_data is not None and (ratio := img_data.get("pixel_ratio", 1)) != 1:
style_opts.append(f"zoom: {1 / ratio:.1f}")
style = f' style="{"; ".join(style_opts)}"' if style_opts else ''
return f'<img{style} src="data:image/png;base64,{img_encoded}"/>'


def get_icon_html(icon: QIcon, size: QSize) -> str:
Expand Down

0 comments on commit 57416ff

Please sign in to comment.