46 lines
1.5 KiB
Python
46 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
from imagepipeline.core.context import ModuleContext
|
|
from imagepipeline.core.params import Param
|
|
from imagepipeline.modules.base import SubprocessModule
|
|
from imagepipeline.modules.registry import register
|
|
from imagepipeline.utils.subprocess import run_command
|
|
|
|
|
|
def build_resize_arguments(*, max_edge: int) -> list[str]:
|
|
if max_edge <= 0:
|
|
raise ValueError("max_edge must be positive")
|
|
return ["-auto-orient", "-resize", f"{max_edge}x{max_edge}>"]
|
|
|
|
|
|
@register
|
|
class ImageMagickResizeModule(SubprocessModule):
|
|
name = "imagemagick_resize"
|
|
description = (
|
|
"Resize images so the longer side is at most max_edge pixels "
|
|
"(aspect ratio preserved; never upscales)"
|
|
)
|
|
command_candidates = ("magick", "convert")
|
|
|
|
@classmethod
|
|
def parameters(cls) -> dict[str, Param]:
|
|
return {
|
|
"max_edge": Param(
|
|
"int",
|
|
default=2000,
|
|
help="Maximum length of the longer side in pixels",
|
|
),
|
|
}
|
|
|
|
def run(self, ctx: ModuleContext) -> None:
|
|
command = self.resolve_command()
|
|
max_edge = ctx.params["max_edge"]
|
|
resize_args = build_resize_arguments(max_edge=max_edge)
|
|
ctx.output_dir.mkdir(parents=True, exist_ok=True)
|
|
total = len(ctx.input_paths)
|
|
|
|
for index, src in enumerate(ctx.input_paths, start=1):
|
|
self.log_image(ctx, index, total, src)
|
|
dst = ctx.output_dir / src.name
|
|
run_command([command, str(src), *resize_args, str(dst)])
|