Skip to content

zimscraperlib.image.conversion

Functions:

convert_image

convert_image(
    src: Path | BytesIO,
    dst: Path | BytesIO,
    **params: str | None,
) -> None

convert an image file from one format to another params: Image.save() parameters. Depends on dest format. params can include the following keys: - fmt: specify the dest format (otherwise guessed from extension) ex: JPEG, PNG, BMP (and other PIL formats) - colorspace: convert to this colorspace. Otherwise not converted unless target format has no halpha channel while source had. In this case converted to RGB. ex: RGB, ARGB, CMYK (and other PIL colorspaces)

Source code in src/zimscraperlib/image/conversion.py
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
def convert_image(
    src: pathlib.Path | io.BytesIO,
    dst: pathlib.Path | io.BytesIO,
    **params: str | None,
) -> None:
    """convert an image file from one format to another
    params: Image.save() parameters. Depends on dest format.
    params can include the following keys:
     - fmt: specify the dest format (otherwise guessed from extension)
            ex: JPEG, PNG, BMP (and other PIL formats)
     - colorspace: convert to this colorspace. Otherwise not converted unless
     target format has no halpha channel while source had. In this case converted
     to RGB. ex: RGB, ARGB, CMYK (and other PIL colorspaces)"""

    colorspace = params.get("colorspace")  # requested colorspace
    fmt = (
        str(params.pop("fmt")).upper() if params.get("fmt") else None
    )  # requested format
    if not fmt:
        fmt = format_for(dst)
    if not fmt:
        raise ValueError("Impossible to guess destination image format")
    with pilopen(src) as image:
        if (image.mode == "RGBA" and fmt in ALPHA_NOT_SUPPORTED) or colorspace:
            image = image.convert(colorspace or "RGB")  # noqa: PLW2901
        save_image(image, dst, fmt, **params)

convert_svg2png

convert_svg2png(
    src: str | Path | BytesIO,
    dst: Path | BytesIO,
    width: int | None = None,
    height: int | None = None,
)

Convert a SVG to a PNG

Output width and height might be specified if resize is needed. PNG background is transparent.

Source code in src/zimscraperlib/image/conversion.py
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
73
74
75
76
def convert_svg2png(
    src: str | pathlib.Path | io.BytesIO,
    dst: pathlib.Path | io.BytesIO,
    width: int | None = None,
    height: int | None = None,
):
    """Convert a SVG to a PNG

    Output width and height might be specified if resize is needed.
    PNG background is transparent.
    """
    kwargs: dict[str, Any] = {}
    if isinstance(src, pathlib.Path):
        src = str(src)
    if isinstance(src, str):
        kwargs["url"] = src
    else:
        kwargs["bytestring"] = src.getvalue()
    if width:
        kwargs["output_width"] = width
    if height:
        kwargs["output_height"] = height
    if isinstance(dst, pathlib.Path):
        cairosvg.svg2png(  # pyright: ignore[reportUnknownMemberType]
            write_to=str(dst), **kwargs
        )
    else:
        result = cairosvg.svg2png(  # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
            **kwargs
        )
        if not isinstance(result, bytes):
            raise Exception(
                "Unexpected type returned by cairosvg.svg2png"
            )  # pragma: no cover
        dst.write(result)

create_favicon

create_favicon(src: Path, dst: Path) -> None

generate a squared favicon from a source image

Source code in src/zimscraperlib/image/conversion.py
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
def create_favicon(src: pathlib.Path, dst: pathlib.Path) -> None:
    """generate a squared favicon from a source image"""
    if dst.suffix != ".ico":
        raise ValueError("favicon extension must be ICO")

    img = pilopen(src)
    w, h = img.size
    # resize image to square first
    if w != h:
        size = min([w, h])
        resized = dst.parent.joinpath(f"{src.stem}.tmp.{src.suffix}")
        resize_image(src, size, size, resized, "contain")
        img = pilopen(resized)
    # now convert to ICO
    save_image(img, dst, "ICO")