mirror of
https://github.com/k4yt3x/video2x.git
synced 2024-12-29 16:09:10 +00:00
redesigned upscaler to use pillow's Lanczos filter for downscaling; bug fixes
This commit is contained in:
parent
2b84e497b5
commit
a8d7f7ecf2
@ -37,7 +37,9 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
# third-party imports
|
# third-party imports
|
||||||
|
from PIL import Image
|
||||||
from avalon_framework import Avalon
|
from avalon_framework import Avalon
|
||||||
|
from tqdm import tqdm
|
||||||
import magic
|
import magic
|
||||||
|
|
||||||
# internationalization constants
|
# internationalization constants
|
||||||
@ -51,7 +53,7 @@ language.install()
|
|||||||
_ = language.gettext
|
_ = language.gettext
|
||||||
|
|
||||||
# version information
|
# version information
|
||||||
UPSCALER_VERSION = '4.3.1'
|
UPSCALER_VERSION = '4.4.0'
|
||||||
|
|
||||||
# these names are consistent for
|
# these names are consistent for
|
||||||
# - driver selection in command line
|
# - driver selection in command line
|
||||||
@ -124,6 +126,7 @@ class Upscaler:
|
|||||||
|
|
||||||
# other internal members and signals
|
# other internal members and signals
|
||||||
self.running = False
|
self.running = False
|
||||||
|
self.current_processing_starting_time = time.time()
|
||||||
self.total_frames_upscaled = 0
|
self.total_frames_upscaled = 0
|
||||||
self.total_frames = 0
|
self.total_frames = 0
|
||||||
self.total_files = 0
|
self.total_files = 0
|
||||||
@ -531,6 +534,9 @@ class Upscaler:
|
|||||||
# get new job from queue
|
# get new job from queue
|
||||||
self.current_input_file, output_path, input_file_mime_type, input_file_type, input_file_subtype = self.processing_queue.get()
|
self.current_input_file, output_path, input_file_mime_type, input_file_type, input_file_subtype = self.processing_queue.get()
|
||||||
|
|
||||||
|
# get current job starting time for GUI calculations
|
||||||
|
self.current_processing_starting_time = time.time()
|
||||||
|
|
||||||
# get video information JSON using FFprobe
|
# get video information JSON using FFprobe
|
||||||
Avalon.info(_('Reading file information'))
|
Avalon.info(_('Reading file information'))
|
||||||
file_info = self.ffmpeg_object.probe_file_info(self.current_input_file)
|
file_info = self.ffmpeg_object.probe_file_info(self.current_input_file)
|
||||||
@ -638,12 +644,6 @@ class Upscaler:
|
|||||||
self.scaling_jobs.append(supported_scaling_ratios[-1])
|
self.scaling_jobs.append(supported_scaling_ratios[-1])
|
||||||
remaining_scaling_ratio /= supported_scaling_ratios[-1]
|
remaining_scaling_ratio /= supported_scaling_ratios[-1]
|
||||||
|
|
||||||
# append scaling filter to video assembly command
|
|
||||||
if self.ffmpeg_settings['assemble_video']['output_options'].get('-vf') is None:
|
|
||||||
self.ffmpeg_settings['assemble_video']['output_options']['-vf'] = f'scale={output_width}:{output_height}'
|
|
||||||
else:
|
|
||||||
self.ffmpeg_settings['assemble_video']['output_options']['-vf'] += f',scale={output_width}:{output_height}'
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.scaling_jobs = [self.scale_ratio]
|
self.scaling_jobs = [self.scale_ratio]
|
||||||
|
|
||||||
@ -696,15 +696,35 @@ class Upscaler:
|
|||||||
Avalon.info(_('Upscaling completed'))
|
Avalon.info(_('Upscaling completed'))
|
||||||
Avalon.info(_('Average processing speed: {} seconds per frame').format(self.total_frames / (time.time() - upscale_begin_time)))
|
Avalon.info(_('Average processing speed: {} seconds per frame').format(self.total_frames / (time.time() - upscale_begin_time)))
|
||||||
|
|
||||||
|
# downscale frames with Lanczos
|
||||||
|
Avalon.info(_('Lanczos downsampling frames'))
|
||||||
|
shutil.rmtree(self.extracted_frames)
|
||||||
|
shutil.move(self.upscaled_frames, self.extracted_frames)
|
||||||
|
self.upscaled_frames.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for image in tqdm([i for i in self.extracted_frames.iterdir() if i.is_file() and i.name.endswith(self.extracted_frame_format)], ascii=True, desc=_('Downsamping')):
|
||||||
|
image_object = Image.open(image)
|
||||||
|
|
||||||
|
# if the image dimensions are not equal to the output size
|
||||||
|
# resize the image using Lanczos
|
||||||
|
if (image_object.width, image_object.height) != (output_width, output_height):
|
||||||
|
image_object.resize((output_width, output_height), Image.LANCZOS).save(self.upscaled_frames / image.name)
|
||||||
|
image_object.close()
|
||||||
|
|
||||||
|
# if the image's dimensions are already equal to the output size
|
||||||
|
# move image to the finished directory
|
||||||
|
else:
|
||||||
|
image_object.close()
|
||||||
|
shutil.move(image, self.upscaled_frames / image.name)
|
||||||
|
|
||||||
# start handling output
|
# start handling output
|
||||||
# output can be either GIF or video
|
# output can be either GIF or video
|
||||||
if input_file_type == 'image' and input_file_subtype != 'gif':
|
if input_file_type == 'image' and input_file_subtype != 'gif':
|
||||||
|
|
||||||
Avalon.info(_('Exporting image'))
|
Avalon.info(_('Exporting image'))
|
||||||
|
|
||||||
# resize and output image to output_path
|
# there should be only one image in the directory
|
||||||
self.process_pool.append(self.ffmpeg_object.resize_image([f for f in self.upscaled_frames.iterdir() if f.is_file()][0], output_path, output_width, output_height))
|
shutil.move([f for f in self.upscaled_frames.iterdir() if f.is_file()][0], output_path)
|
||||||
self._wait()
|
|
||||||
|
|
||||||
# elif input_file_mime_type == 'image/gif' or input_file_type == 'video':
|
# elif input_file_mime_type == 'image/gif' or input_file_type == 'video':
|
||||||
else:
|
else:
|
||||||
@ -765,10 +785,10 @@ class Upscaler:
|
|||||||
Avalon.info(_('Writing intermediate file to: {}').format(output_video_path.absolute()))
|
Avalon.info(_('Writing intermediate file to: {}').format(output_video_path.absolute()))
|
||||||
shutil.move(self.upscaled_frames / self.ffmpeg_object.intermediate_file_name, output_video_path)
|
shutil.move(self.upscaled_frames / self.ffmpeg_object.intermediate_file_name, output_video_path)
|
||||||
|
|
||||||
# increment total number of files processed
|
# increment total number of files processed
|
||||||
self.cleanup_temp_directories()
|
self.cleanup_temp_directories()
|
||||||
self.processing_queue.task_done()
|
self.processing_queue.task_done()
|
||||||
self.total_processed += 1
|
self.total_processed += 1
|
||||||
|
|
||||||
except (Exception, KeyboardInterrupt, SystemExit) as e:
|
except (Exception, KeyboardInterrupt, SystemExit) as e:
|
||||||
with contextlib.suppress(ValueError, AttributeError):
|
with contextlib.suppress(ValueError, AttributeError):
|
||||||
|
Loading…
Reference in New Issue
Block a user