Skip to content

Commit a68a4e1

Browse files
authored
feat(cli): speedup scaling with painter scaling (#88)
As suggested by PySide6's documentation, we avoid using pixmap.scaled() on every frame, but use scaled content to resize the image. This seems to ignore ratio, explaining why we need a new option flag.
1 parent 519dd47 commit a68a4e1

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

manim_slides/present.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import platform
33
import sys
44
import time
5-
from enum import IntEnum, auto, unique
5+
from enum import Enum, IntEnum, auto, unique
66
from typing import Any, Dict, List, Optional, Tuple, Union
77

88
import click
@@ -28,9 +28,17 @@
2828
WINDOW_INFO_NAME = f"{WINDOW_NAME}: Info"
2929
WINDOWS = platform.system() == "Windows"
3030

31+
32+
class AspectRatio(Enum):
33+
ignore = Qt.IgnoreAspectRatio
34+
keep = Qt.KeepAspectRatio
35+
auto = "auto"
36+
37+
3138
ASPECT_RATIO_MODES = {
32-
"ignore": Qt.IgnoreAspectRatio,
33-
"keep": Qt.KeepAspectRatio,
39+
"ignore": AspectRatio.ignore,
40+
"keep": AspectRatio.keep,
41+
"auto": AspectRatio.auto,
3442
}
3543

3644
RESIZE_MODES = {
@@ -514,7 +522,7 @@ def __init__(
514522
fullscreen: bool = False,
515523
resolution: Tuple[int, int] = (1980, 1080),
516524
hide_mouse: bool = False,
517-
aspect_ratio: Qt.AspectRatioMode = Qt.IgnoreAspectRatio,
525+
aspect_ratio: AspectRatio = AspectRatio.auto,
518526
resize_mode: Qt.TransformationMode = Qt.SmoothTransformation,
519527
background_color: str = "black",
520528
**kwargs: Any,
@@ -533,6 +541,9 @@ def __init__(
533541
self.setCursor(Qt.BlankCursor)
534542

535543
self.label = QLabel(self)
544+
545+
if self.aspect_ratio == AspectRatio.auto:
546+
self.label.setScaledContents(True)
536547
self.label.setAlignment(Qt.AlignCenter)
537548
self.label.resize(self.display_width, self.display_height)
538549
self.label.setStyleSheet(f"background-color: {background_color}")
@@ -584,10 +595,11 @@ def closeAll(self) -> None:
584595
self.deleteLater()
585596

586597
def resizeEvent(self, event: QResizeEvent) -> None:
587-
self.pixmap = self.pixmap.scaled(
588-
self.width(), self.height(), self.aspect_ratio, self.resize_mode
589-
)
590-
self.label.setPixmap(self.pixmap)
598+
if not self.label.hasScaledContents():
599+
self.pixmap = self.pixmap.scaled(
600+
self.width(), self.height(), self.aspect_ratio.value, self.resize_mode
601+
)
602+
self.label.setPixmap(self.pixmap)
591603
self.label.resize(self.width(), self.height())
592604

593605
def closeEvent(self, event: QCloseEvent) -> None:
@@ -601,9 +613,11 @@ def update_image(self, cv_img: np.ndarray) -> None:
601613
bytes_per_line = ch * w
602614
qt_img = QImage(cv_img.data, w, h, bytes_per_line, QImage.Format_BGR888)
603615

604-
if w != self.width() or h != self.height():
616+
if not self.label.hasScaledContents() and (
617+
w != self.width() or h != self.height()
618+
):
605619
qt_img = qt_img.scaled(
606-
self.width(), self.height(), self.aspect_ratio, self.resize_mode
620+
self.width(), self.height(), self.aspect_ratio.value, self.resize_mode
607621
)
608622

609623
self.label.setPixmap(QPixmap.fromImage(qt_img))
@@ -755,8 +769,8 @@ def get_scenes_presentation_config(
755769
@click.option(
756770
"--aspect-ratio",
757771
type=click.Choice(ASPECT_RATIO_MODES.keys(), case_sensitive=False),
758-
default="ignore",
759-
help="Set the aspect ratio mode to be used when rescaling video.",
772+
default="auto",
773+
help="Set the aspect ratio mode to be used when rescaling video. `'auto'` option is equivalent to `'ignore'`, but can be much faster due to not calling `scaled()` method on every frame.",
760774
show_default=True,
761775
)
762776
@click.option(

0 commit comments

Comments
 (0)