Skip to content

Commit 84c25f1

Browse files
fix(ui): enhance window quality (#22)
* fix(ui): enhance window quality This fix always resizes the frame size, as this seems to be a good cross-platform fix to the quality issue that occurs when the frame does not match the window size. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: remove unused import * fix: actually only resize on Windows * feat(cli): optional interpolation flag * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * chore: add image fox windows quality fix * chore(README): document Windows fix Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 7fb3fa0 commit 84c25f1

File tree

4 files changed

+67
-39
lines changed

4 files changed

+67
-39
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Tool for live presentations using either [Manim (community edition)](https://www
99

1010
> **_NOTE:_** This project extends the work of [`manim-presentation`](https://github.com/galatolofederico/manim-presentation), with a lot more features!
1111
12-
- [Install](#install)
12+
- [Installation](#installation)
1313
* [Dependencies](#dependencies)
1414
* [Pip install](#pip-install)
1515
* [Install From Repository](#install-from-repository)
@@ -18,6 +18,8 @@ Tool for live presentations using either [Manim (community edition)](https://www
1818
* [Key Bindings](#key-bindings)
1919
* [Other Examples](#other-examples)
2020
- [Features and Comparison with Original manim-presentation](#features-and-comparison-with-original-manim-presentation)
21+
- [F.A.Q](#faq)
22+
* [How to increase quality on Windows](#how-to-increase-quality-on-windows)
2123
- [Contributing](#contributing)
2224

2325
## Installation
@@ -168,6 +170,16 @@ Below is a non-exhaustive list of features:
168170
| Documented code | :heavy_check_mark: | :heavy_multiplication_x: |
169171
| Tested on Unix, macOS, and Windows | :heavy_check_mark: | :heavy_multiplication_x: |
170172

173+
## F.A.Q
174+
175+
### How to increase quality on Windows
176+
177+
On Windows platform, one may encounter a lower image resolution than expected. Usually, this is observed because Windows rescales every application to fit the screen.
178+
As found by [@arashash](https://github.com/arashash), in [#20](https://github.com/jeertmans/manim-slides/issues/20), the problem can be addressed by changing the scaling factor to 100%:
179+
180+
![Windows Fix Scaling](static/windows_quality_fix.png)
181+
182+
in *Settings*->*Display*.
171183

172184
## Contributing
173185

manim_slides/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from enum import Enum
33
from typing import List, Optional, Set
44

5-
from pydantic import BaseModel, FilePath, root_validator, validator
5+
from pydantic import BaseModel, root_validator, validator
66

77
from .defaults import LEFT_ARROW_KEY_CODE, RIGHT_ARROW_KEY_CODE
88

manim_slides/present.py

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
from enum import IntEnum, auto, unique
88
from typing import List, Tuple
99

10-
if platform.system() == "Windows":
11-
import ctypes
12-
1310
import click
1411
import cv2
1512
import numpy as np
@@ -19,8 +16,19 @@
1916
from .config import Config, PresentationConfig, SlideConfig, SlideType
2017
from .defaults import CONFIG_PATH, FOLDER_PATH, FONT_ARGS
2118

19+
INTERPOLATION_FLAGS = {
20+
"nearest": cv2.INTER_NEAREST,
21+
"linear": cv2.INTER_LINEAR,
22+
"cubic": cv2.INTER_CUBIC,
23+
"area": cv2.INTER_AREA,
24+
"lanczos4": cv2.INTER_LANCZOS4,
25+
"linear-exact": cv2.INTER_LINEAR_EXACT,
26+
"nearest-exact": cv2.INTER_NEAREST_EXACT,
27+
}
28+
2229
WINDOW_NAME = "Manim Slides"
2330
WINDOW_INFO_NAME = f"{WINDOW_NAME}: Info"
31+
WINDOWS = platform.system() == "Windows"
2432

2533

2634
@unique
@@ -252,14 +260,19 @@ def __init__(
252260
start_paused=False,
253261
fullscreen=False,
254262
skip_all=False,
255-
resolution=(1280, 720),
263+
resolution=(1980, 1080),
264+
interpolation_flag=cv2.INTER_LINEAR,
256265
):
257266
self.presentations = presentations
258267
self.start_paused = start_paused
259268
self.config = config
260269
self.skip_all = skip_all
261270
self.fullscreen = fullscreen
262-
self.is_windows = platform.system() == "Windows"
271+
self.resolution = resolution
272+
self.interpolation_flag = interpolation_flag
273+
self.window_flags = (
274+
cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_NORMAL
275+
)
263276

264277
self.state = State.PLAYING
265278
self.lastframe = None
@@ -274,39 +287,16 @@ def __init__(
274287
cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_AUTOSIZE,
275288
)
276289

277-
if self.is_windows:
278-
user32 = ctypes.windll.user32
279-
self.screen_width, self.screen_height = user32.GetSystemMetrics(
280-
0
281-
), user32.GetSystemMetrics(1)
282-
283290
if self.fullscreen:
284-
cv2.namedWindow(WINDOW_NAME, cv2.WND_PROP_FULLSCREEN)
291+
cv2.namedWindow(
292+
WINDOW_NAME, cv2.WINDOW_GUI_NORMAL | cv2.WND_PROP_FULLSCREEN
293+
)
285294
cv2.setWindowProperty(
286295
WINDOW_NAME, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN
287296
)
288297
else:
289-
cv2.namedWindow(
290-
WINDOW_NAME,
291-
cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_NORMAL,
292-
)
293-
cv2.resizeWindow(WINDOW_NAME, *resolution)
294-
295-
def resize_frame_to_screen(self, frame: np.ndarray) -> np.ndarray:
296-
"""
297-
Resizes a given frame to match screen dimensions.
298-
299-
Only works on Windows.
300-
"""
301-
assert self.is_windows, "Only Windows platforms need this method"
302-
frame_height, frame_width = frame.shape[:2]
303-
304-
scale_height = self.screen_height / frame_height
305-
scale_width = self.screen_width / frame_width
306-
307-
scale = min(scale_height, scale_width)
308-
309-
return cv2.resize(frame, (int(scale * frame_height), int(scale * frame_width)))
298+
cv2.namedWindow(WINDOW_NAME, self.window_flags)
299+
cv2.resizeWindow(WINDOW_NAME, *self.resolution)
310300

311301
@property
312302
def current_presentation(self) -> Presentation:
@@ -343,8 +333,17 @@ def show_video(self):
343333

344334
frame = self.lastframe
345335

346-
if self.is_windows and self.fullscreen:
347-
frame = self.resize_frame_to_screen(frame)
336+
# If Window was manually closed (impossible in fullscreen),
337+
# we reopen it
338+
if cv2.getWindowProperty(WINDOW_NAME, cv2.WND_PROP_VISIBLE) < 1:
339+
cv2.namedWindow(WINDOW_NAME, self.window_flags)
340+
cv2.resizeWindow(WINDOW_NAME, *self.resolution)
341+
342+
if WINDOWS: # Only resize on Windows
343+
_, _, w, h = cv2.getWindowImageRect(WINDOW_NAME)
344+
345+
if (h, w) != frame.shape[:2]: # Only if shape is different
346+
frame = cv2.resize(frame, (w, h), self.interpolation_flag)
348347

349348
cv2.imshow(WINDOW_NAME, frame)
350349

@@ -477,15 +476,31 @@ def _list_scenes(folder) -> List[str]:
477476
help="Skip all slides, useful the test if slides are working.",
478477
)
479478
@click.option(
479+
"-r",
480480
"--resolution",
481481
type=(int, int),
482-
default=(1280, 720),
482+
default=(1920, 1080),
483483
help="Window resolution used if fullscreen is not set. You may manually resize the window afterward.",
484484
show_default=True,
485485
)
486+
@click.option(
487+
"-i",
488+
"--interpolation-flag",
489+
type=click.Choice(INTERPOLATION_FLAGS.keys(), case_sensitive=False),
490+
default="linear",
491+
help="Set the interpolation flag to be used when resizing image. See OpenCV cv::InterpolationFlags.",
492+
show_default=True,
493+
)
486494
@click.help_option("-h", "--help")
487495
def present(
488-
scenes, config_path, folder, start_paused, fullscreen, skip_all, resolution
496+
scenes,
497+
config_path,
498+
folder,
499+
start_paused,
500+
fullscreen,
501+
skip_all,
502+
resolution,
503+
interpolation_flag,
489504
):
490505
"""Present the different scenes."""
491506

@@ -552,5 +567,6 @@ def value_proc(value: str):
552567
fullscreen=fullscreen,
553568
skip_all=skip_all,
554569
resolution=resolution,
570+
interpolation_flag=INTERPOLATION_FLAGS[interpolation_flag],
555571
)
556572
display.run()

static/windows_quality_fix.png

34.6 KB
Loading

0 commit comments

Comments
 (0)