From 84c25f1ed5467aac8fbc536f4ac2edc20d09d786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Wed, 21 Sep 2022 09:15:12 +0200 Subject: [PATCH] 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> --- README.md | 14 ++++- manim_slides/config.py | 2 +- manim_slides/present.py | 90 +++++++++++++++++++-------------- static/windows_quality_fix.png | Bin 0 -> 35437 bytes 4 files changed, 67 insertions(+), 39 deletions(-) create mode 100644 static/windows_quality_fix.png diff --git a/README.md b/README.md index c35b8ec..c33f7a6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Tool for live presentations using either [Manim (community edition)](https://www > **_NOTE:_** This project extends the work of [`manim-presentation`](https://github.com/galatolofederico/manim-presentation), with a lot more features! -- [Install](#install) +- [Installation](#installation) * [Dependencies](#dependencies) * [Pip install](#pip-install) * [Install From Repository](#install-from-repository) @@ -18,6 +18,8 @@ Tool for live presentations using either [Manim (community edition)](https://www * [Key Bindings](#key-bindings) * [Other Examples](#other-examples) - [Features and Comparison with Original manim-presentation](#features-and-comparison-with-original-manim-presentation) +- [F.A.Q](#faq) + * [How to increase quality on Windows](#how-to-increase-quality-on-windows) - [Contributing](#contributing) ## Installation @@ -168,6 +170,16 @@ Below is a non-exhaustive list of features: | Documented code | :heavy_check_mark: | :heavy_multiplication_x: | | Tested on Unix, macOS, and Windows | :heavy_check_mark: | :heavy_multiplication_x: | +## F.A.Q + +### How to increase quality on Windows + +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. +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%: + +![Windows Fix Scaling](static/windows_quality_fix.png) + +in *Settings*->*Display*. ## Contributing diff --git a/manim_slides/config.py b/manim_slides/config.py index 1d0989b..9d57f07 100644 --- a/manim_slides/config.py +++ b/manim_slides/config.py @@ -2,7 +2,7 @@ import os from enum import Enum from typing import List, Optional, Set -from pydantic import BaseModel, FilePath, root_validator, validator +from pydantic import BaseModel, root_validator, validator from .defaults import LEFT_ARROW_KEY_CODE, RIGHT_ARROW_KEY_CODE diff --git a/manim_slides/present.py b/manim_slides/present.py index 5d500ce..d1f2ca3 100644 --- a/manim_slides/present.py +++ b/manim_slides/present.py @@ -7,9 +7,6 @@ import time from enum import IntEnum, auto, unique from typing import List, Tuple -if platform.system() == "Windows": - import ctypes - import click import cv2 import numpy as np @@ -19,8 +16,19 @@ from .commons import config_path_option from .config import Config, PresentationConfig, SlideConfig, SlideType from .defaults import CONFIG_PATH, FOLDER_PATH, FONT_ARGS +INTERPOLATION_FLAGS = { + "nearest": cv2.INTER_NEAREST, + "linear": cv2.INTER_LINEAR, + "cubic": cv2.INTER_CUBIC, + "area": cv2.INTER_AREA, + "lanczos4": cv2.INTER_LANCZOS4, + "linear-exact": cv2.INTER_LINEAR_EXACT, + "nearest-exact": cv2.INTER_NEAREST_EXACT, +} + WINDOW_NAME = "Manim Slides" WINDOW_INFO_NAME = f"{WINDOW_NAME}: Info" +WINDOWS = platform.system() == "Windows" @unique @@ -252,14 +260,19 @@ class Display: start_paused=False, fullscreen=False, skip_all=False, - resolution=(1280, 720), + resolution=(1980, 1080), + interpolation_flag=cv2.INTER_LINEAR, ): self.presentations = presentations self.start_paused = start_paused self.config = config self.skip_all = skip_all self.fullscreen = fullscreen - self.is_windows = platform.system() == "Windows" + self.resolution = resolution + self.interpolation_flag = interpolation_flag + self.window_flags = ( + cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_NORMAL + ) self.state = State.PLAYING self.lastframe = None @@ -274,39 +287,16 @@ class Display: cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_AUTOSIZE, ) - if self.is_windows: - user32 = ctypes.windll.user32 - self.screen_width, self.screen_height = user32.GetSystemMetrics( - 0 - ), user32.GetSystemMetrics(1) - if self.fullscreen: - cv2.namedWindow(WINDOW_NAME, cv2.WND_PROP_FULLSCREEN) + cv2.namedWindow( + WINDOW_NAME, cv2.WINDOW_GUI_NORMAL | cv2.WND_PROP_FULLSCREEN + ) cv2.setWindowProperty( WINDOW_NAME, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN ) else: - cv2.namedWindow( - WINDOW_NAME, - cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_FREERATIO | cv2.WINDOW_NORMAL, - ) - cv2.resizeWindow(WINDOW_NAME, *resolution) - - def resize_frame_to_screen(self, frame: np.ndarray) -> np.ndarray: - """ - Resizes a given frame to match screen dimensions. - - Only works on Windows. - """ - assert self.is_windows, "Only Windows platforms need this method" - frame_height, frame_width = frame.shape[:2] - - scale_height = self.screen_height / frame_height - scale_width = self.screen_width / frame_width - - scale = min(scale_height, scale_width) - - return cv2.resize(frame, (int(scale * frame_height), int(scale * frame_width))) + cv2.namedWindow(WINDOW_NAME, self.window_flags) + cv2.resizeWindow(WINDOW_NAME, *self.resolution) @property def current_presentation(self) -> Presentation: @@ -343,8 +333,17 @@ class Display: frame = self.lastframe - if self.is_windows and self.fullscreen: - frame = self.resize_frame_to_screen(frame) + # If Window was manually closed (impossible in fullscreen), + # we reopen it + if cv2.getWindowProperty(WINDOW_NAME, cv2.WND_PROP_VISIBLE) < 1: + cv2.namedWindow(WINDOW_NAME, self.window_flags) + cv2.resizeWindow(WINDOW_NAME, *self.resolution) + + if WINDOWS: # Only resize on Windows + _, _, w, h = cv2.getWindowImageRect(WINDOW_NAME) + + if (h, w) != frame.shape[:2]: # Only if shape is different + frame = cv2.resize(frame, (w, h), self.interpolation_flag) cv2.imshow(WINDOW_NAME, frame) @@ -477,15 +476,31 @@ def _list_scenes(folder) -> List[str]: help="Skip all slides, useful the test if slides are working.", ) @click.option( + "-r", "--resolution", type=(int, int), - default=(1280, 720), + default=(1920, 1080), help="Window resolution used if fullscreen is not set. You may manually resize the window afterward.", show_default=True, ) +@click.option( + "-i", + "--interpolation-flag", + type=click.Choice(INTERPOLATION_FLAGS.keys(), case_sensitive=False), + default="linear", + help="Set the interpolation flag to be used when resizing image. See OpenCV cv::InterpolationFlags.", + show_default=True, +) @click.help_option("-h", "--help") def present( - scenes, config_path, folder, start_paused, fullscreen, skip_all, resolution + scenes, + config_path, + folder, + start_paused, + fullscreen, + skip_all, + resolution, + interpolation_flag, ): """Present the different scenes.""" @@ -552,5 +567,6 @@ def present( fullscreen=fullscreen, skip_all=skip_all, resolution=resolution, + interpolation_flag=INTERPOLATION_FLAGS[interpolation_flag], ) display.run() diff --git a/static/windows_quality_fix.png b/static/windows_quality_fix.png new file mode 100644 index 0000000000000000000000000000000000000000..3ae84034c74d962a4721d10fd874b4f49f08475a GIT binary patch literal 35437 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 sjjfE0v<(cb3=Ed~yzopr0CuG=z5oCK literal 0 HcmV?d00001