resize_image(
src: Path | BytesIO,
width: int,
height: int | None = None,
dst: Path | BytesIO | None = None,
method: str | None = "width",
*,
allow_upscaling: bool | None = True,
**params: str,
) -> None
resize an image to requested dimensions
methods: width, height, cover, thumbnail
allow upscaling: upscale image first, preserving aspect ratio if required
Source code in src/zimscraperlib/image/transformation.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 | def resize_image(
src: pathlib.Path | io.BytesIO,
width: int,
height: int | None = None,
dst: pathlib.Path | io.BytesIO | None = None,
method: str | None = "width",
*,
allow_upscaling: bool | None = True,
**params: str,
) -> None:
"""resize an image to requested dimensions
methods: width, height, cover, thumbnail
allow upscaling: upscale image first, preserving aspect ratio if required"""
with pilopen(src) as image:
# preserve image format as resize() does not transmit it into new object
image_format = image.format
image_mode = image.mode
# upscale if required preserving the aspect ratio
if allow_upscaling:
height_width_ratio = float(image.size[1]) / float(image.size[0])
if image.size[0] < width:
image = image.resize( # noqa: PLW2901 # pyright: ignore[reportUnknownMemberType]
(width, int(width * height_width_ratio))
)
if height and image.size[1] < height:
image = image.resize( # noqa: PLW2901 # pyright: ignore[reportUnknownMemberType]
(int(height / height_width_ratio), height)
)
# resize using the requested method
if method == "width":
resized = resizeimage.resize( # pyright: ignore[reportUnknownMemberType]
method, image, width
)
elif method == "height":
resized = resizeimage.resize( # pyright: ignore[reportUnknownMemberType]
method, image, height
)
else:
resized = resizeimage.resize( # pyright: ignore[reportUnknownMemberType]
method, image, [width, height]
)
# remove alpha layer if not supported and added during resizing
if resized.mode == "RGBA" and image_format in ALPHA_NOT_SUPPORTED:
resized = resized.convert(image_mode)
# reset src if it's a byte stream and should be resized in-place
if dst is None and isinstance(src, io.BytesIO):
src.seek(0)
if image_format is None: # pragma: no cover
raise ValueError("Impossible to guess format from src image")
save_image(
resized,
dst if dst is not None else src,
image_format,
**params,
)
|