Coverage for pyguymer3/image/optipng.py: 86%
14 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
« prev ^ index » next coverage.py v7.9.2, created at 2025-07-08 18:47 +0000
1#!/usr/bin/env python3
3# Define function ...
4def optipng(
5 fname,
6 /,
7 *,
8 optipngPath = None,
9 pool = None,
10 timeout = 60.0,
11):
12 """
13 "optipng" does not modify, and it does not touch, the image even if it
14 cannot make it smaller, therefore it is safe to keep on running "optipng" on
15 the same PNG over and over again.
16 """
18 # Import standard modules ...
19 import multiprocessing
20 import multiprocessing.pool
21 import os
22 import shutil
23 import subprocess
25 # **************************************************************************
27 # Try to find the paths if the user did not provide them ...
28 if optipngPath is None:
29 optipngPath = shutil.which("optipng")
30 assert optipngPath is not None, "\"optipng\" is not installed"
32 # Check that the image exists ...
33 if not os.path.exists(fname):
34 raise Exception(f"\"{fname}\" does not exist") from None
36 # Check if the user wants to be asynchronous ...
37 if isinstance(pool, multiprocessing.pool.Pool):
38 # Optimise PNG asynchronously ...
39 # NOTE: I have to use the "--" argument to "optipng" in case the user
40 # supplies a file name which starts with "-".
41 pool.apply_async(
42 subprocess.run,
43 [
44 [
45 optipngPath,
46 "-strip", "all",
47 "--",
48 fname,
49 ]
50 ],
51 {
52 "check" : True,
53 "encoding" : "utf-8",
54 "stderr" : subprocess.DEVNULL,
55 "stdout" : subprocess.DEVNULL,
56 "timeout" : timeout,
57 },
58 )
59 else:
60 # Optimise PNG synchronously ...
61 # NOTE: I have to use the "--" argument to "optipng" in case the user
62 # supplies a file name which starts with "-".
63 subprocess.run(
64 [
65 optipngPath,
66 "-strip", "all",
67 "--",
68 fname,
69 ],
70 check = True,
71 encoding = "utf-8",
72 stderr = subprocess.DEVNULL,
73 stdout = subprocess.DEVNULL,
74 timeout = timeout,
75 )