fotolab 0.31.1__py3-none-any.whl → 0.31.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fotolab/__init__.py +2 -1
- fotolab/subcommands/__init__.py +1 -2
- fotolab/subcommands/animate.py +1 -4
- fotolab/subcommands/border.py +2 -8
- fotolab/subcommands/contrast.py +3 -9
- fotolab/subcommands/halftone.py +2 -6
- fotolab/subcommands/info.py +1 -3
- fotolab/subcommands/montage.py +1 -3
- fotolab/subcommands/resize.py +1 -4
- fotolab/subcommands/watermark.py +5 -17
- {fotolab-0.31.1.dist-info → fotolab-0.31.4.dist-info}/METADATA +7 -12
- fotolab-0.31.4.dist-info/RECORD +21 -0
- {fotolab-0.31.1.dist-info → fotolab-0.31.4.dist-info}/WHEEL +1 -1
- fotolab-0.31.1.dist-info/RECORD +0 -21
- {fotolab-0.31.1.dist-info → fotolab-0.31.4.dist-info}/entry_points.txt +0 -0
- {fotolab-0.31.1.dist-info → fotolab-0.31.4.dist-info/licenses}/LICENSE.md +0 -0
fotolab/__init__.py
CHANGED
@@ -20,11 +20,12 @@ import logging
|
|
20
20
|
import os
|
21
21
|
import subprocess
|
22
22
|
import sys
|
23
|
+
from importlib import metadata
|
23
24
|
from pathlib import Path
|
24
25
|
|
25
26
|
from PIL import Image
|
26
27
|
|
27
|
-
__version__ =
|
28
|
+
__version__ = metadata.version("fotolab")
|
28
29
|
|
29
30
|
log = logging.getLogger(__name__)
|
30
31
|
|
fotolab/subcommands/__init__.py
CHANGED
@@ -24,8 +24,7 @@ def build_subparser(subparsers):
|
|
24
24
|
iter_namespace = pkgutil.iter_modules(__path__, __name__ + ".")
|
25
25
|
|
26
26
|
subcommands = {
|
27
|
-
name: importlib.import_module(name)
|
28
|
-
for finder, name, ispkg in iter_namespace
|
27
|
+
name: importlib.import_module(name) for finder, name, ispkg in iter_namespace
|
29
28
|
}
|
30
29
|
|
31
30
|
for subcommand in subcommands.values():
|
fotolab/subcommands/animate.py
CHANGED
@@ -123,10 +123,7 @@ def build_subparser(subparsers) -> None:
|
|
123
123
|
type=int,
|
124
124
|
default=4,
|
125
125
|
choices=range(0, 7),
|
126
|
-
help=(
|
127
|
-
"set WEBP encoding method "
|
128
|
-
"(0=fast, 6=slow/best, default: '%(default)s')"
|
129
|
-
),
|
126
|
+
help=("set WEBP encoding method (0=fast, 6=slow/best, default: '%(default)s')"),
|
130
127
|
metavar="METHOD",
|
131
128
|
)
|
132
129
|
|
fotolab/subcommands/border.py
CHANGED
@@ -77,10 +77,7 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
77
77
|
dest="width_right",
|
78
78
|
type=int,
|
79
79
|
default=0,
|
80
|
-
help=(
|
81
|
-
"set the width of right border in pixels"
|
82
|
-
" (default: '%(default)s')"
|
83
|
-
),
|
80
|
+
help=("set the width of right border in pixels (default: '%(default)s')"),
|
84
81
|
metavar="WIDTH",
|
85
82
|
)
|
86
83
|
|
@@ -90,10 +87,7 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
90
87
|
dest="width_bottom",
|
91
88
|
type=int,
|
92
89
|
default=0,
|
93
|
-
help=(
|
94
|
-
"set the width of bottom border in pixels"
|
95
|
-
" (default: '%(default)s')"
|
96
|
-
),
|
90
|
+
help=("set the width of bottom border in pixels (default: '%(default)s')"),
|
97
91
|
metavar="WIDTH",
|
98
92
|
)
|
99
93
|
|
fotolab/subcommands/contrast.py
CHANGED
@@ -31,9 +31,7 @@ def _validate_cutoff(value: str) -> float:
|
|
31
31
|
try:
|
32
32
|
f_value = float(value)
|
33
33
|
except ValueError as e:
|
34
|
-
raise argparse.ArgumentTypeError(
|
35
|
-
f"invalid float value: '{value}'"
|
36
|
-
) from e
|
34
|
+
raise argparse.ArgumentTypeError(f"invalid float value: '{value}'") from e
|
37
35
|
if not 0 <= f_value <= 50:
|
38
36
|
raise argparse.ArgumentTypeError(
|
39
37
|
f"cutoff value {f_value} must be between 0 and 50"
|
@@ -43,9 +41,7 @@ def _validate_cutoff(value: str) -> float:
|
|
43
41
|
|
44
42
|
def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
45
43
|
"""Build the subparser."""
|
46
|
-
contrast_parser = subparsers.add_parser(
|
47
|
-
"contrast", help="contrast an image."
|
48
|
-
)
|
44
|
+
contrast_parser = subparsers.add_parser("contrast", help="contrast an image.")
|
49
45
|
|
50
46
|
contrast_parser.set_defaults(func=run)
|
51
47
|
|
@@ -103,8 +99,6 @@ def run(args: argparse.Namespace) -> None:
|
|
103
99
|
|
104
100
|
for image_filename in args.image_filenames:
|
105
101
|
original_image = Image.open(image_filename)
|
106
|
-
contrast_image = ImageOps.autocontrast(
|
107
|
-
original_image, cutoff=args.cutoff
|
108
|
-
)
|
102
|
+
contrast_image = ImageOps.autocontrast(original_image, cutoff=args.cutoff)
|
109
103
|
|
110
104
|
save_image(args, contrast_image, image_filename, "contrast")
|
fotolab/subcommands/halftone.py
CHANGED
@@ -37,9 +37,7 @@ class HalftoneCell(NamedTuple):
|
|
37
37
|
|
38
38
|
def build_subparser(subparsers) -> None:
|
39
39
|
"""Build the subparser."""
|
40
|
-
halftone_parser = subparsers.add_parser(
|
41
|
-
"halftone", help="halftone an image"
|
42
|
-
)
|
40
|
+
halftone_parser = subparsers.add_parser("halftone", help="halftone an image")
|
43
41
|
|
44
42
|
halftone_parser.set_defaults(func=run)
|
45
43
|
|
@@ -156,9 +154,7 @@ def _draw_halftone_dot(
|
|
156
154
|
else:
|
157
155
|
# Calculate brightness (luminance) from the RGB color
|
158
156
|
brightness = int(
|
159
|
-
0.299 * pixel_value[0]
|
160
|
-
+ 0.587 * pixel_value[1]
|
161
|
-
+ 0.114 * pixel_value[2]
|
157
|
+
0.299 * pixel_value[0] + 0.587 * pixel_value[1] + 0.114 * pixel_value[2]
|
162
158
|
)
|
163
159
|
dot_fill = pixel_value # Use original color for color dots
|
164
160
|
|
fotolab/subcommands/info.py
CHANGED
@@ -107,9 +107,7 @@ def extract_exif_tags(image: Image.Image, sort: bool = False) -> dict:
|
|
107
107
|
if exif:
|
108
108
|
info = {ExifTags.TAGS.get(tag_id): exif.get(tag_id) for tag_id in exif}
|
109
109
|
|
110
|
-
filtered_info = {
|
111
|
-
key: value for key, value in info.items() if key is not None
|
112
|
-
}
|
110
|
+
filtered_info = {key: value for key, value in info.items() if key is not None}
|
113
111
|
if sort:
|
114
112
|
filtered_info = dict(sorted(filtered_info.items()))
|
115
113
|
|
fotolab/subcommands/montage.py
CHANGED
@@ -27,9 +27,7 @@ log = logging.getLogger(__name__)
|
|
27
27
|
|
28
28
|
def build_subparser(subparsers) -> None:
|
29
29
|
"""Build the subparser."""
|
30
|
-
montage_parser = subparsers.add_parser(
|
31
|
-
"montage", help="montage a list of image"
|
32
|
-
)
|
30
|
+
montage_parser = subparsers.add_parser("montage", help="montage a list of image")
|
33
31
|
|
34
32
|
montage_parser.set_defaults(func=run)
|
35
33
|
|
fotolab/subcommands/resize.py
CHANGED
@@ -59,10 +59,7 @@ def build_subparser(subparsers) -> None:
|
|
59
59
|
"--canvas-color",
|
60
60
|
default="black",
|
61
61
|
dest="canvas_color",
|
62
|
-
help=(
|
63
|
-
"the color of the extended larger canvas"
|
64
|
-
"(default: '%(default)s')"
|
65
|
-
),
|
62
|
+
help=("the color of the extended larger canvas(default: '%(default)s')"),
|
66
63
|
)
|
67
64
|
|
68
65
|
if "-c" in sys.argv or "--canvas" in sys.argv:
|
fotolab/subcommands/watermark.py
CHANGED
@@ -109,10 +109,7 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
109
109
|
dest="outline_width",
|
110
110
|
type=int,
|
111
111
|
default=2,
|
112
|
-
help=(
|
113
|
-
"set the outline width of the watermark text "
|
114
|
-
"(default: '%(default)s')"
|
115
|
-
),
|
112
|
+
help=("set the outline width of the watermark text (default: '%(default)s')"),
|
116
113
|
metavar="OUTLINE_WIDTH",
|
117
114
|
)
|
118
115
|
|
@@ -122,10 +119,7 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
122
119
|
dest="outline_color",
|
123
120
|
type=str,
|
124
121
|
default="black",
|
125
|
-
help=(
|
126
|
-
"set the outline color of the watermark text "
|
127
|
-
"(default: '%(default)s')"
|
128
|
-
),
|
122
|
+
help=("set the outline color of the watermark text (default: '%(default)s')"),
|
129
123
|
metavar="OUTLINE_COLOR",
|
130
124
|
)
|
131
125
|
|
@@ -203,9 +197,7 @@ def run(args: argparse.Namespace) -> None:
|
|
203
197
|
if image.format == "GIF":
|
204
198
|
watermark_gif_image(image, image_filename, args)
|
205
199
|
else:
|
206
|
-
watermarked_image: Image.Image = watermark_non_gif_image(
|
207
|
-
image, args
|
208
|
-
)
|
200
|
+
watermarked_image: Image.Image = watermark_non_gif_image(image, args)
|
209
201
|
save_image(args, watermarked_image, image_filename, "watermark")
|
210
202
|
|
211
203
|
|
@@ -341,16 +333,12 @@ def calc_font_size(image: Image.Image, args: argparse.Namespace) -> int:
|
|
341
333
|
return new_font_size
|
342
334
|
|
343
335
|
|
344
|
-
def calc_font_outline_width(
|
345
|
-
image: Image.Image, args: argparse.Namespace
|
346
|
-
) -> int:
|
336
|
+
def calc_font_outline_width(image: Image.Image, args: argparse.Namespace) -> int:
|
347
337
|
"""Calculate the font padding based on the width of the image."""
|
348
338
|
width, _height = image.size
|
349
339
|
new_font_outline_width: int = args.outline_width
|
350
340
|
if width > 600:
|
351
|
-
new_font_outline_width = math.floor(
|
352
|
-
FONT_OUTLINE_WIDTH_ASPECT_RATIO * width
|
353
|
-
)
|
341
|
+
new_font_outline_width = math.floor(FONT_OUTLINE_WIDTH_ASPECT_RATIO * width)
|
354
342
|
|
355
343
|
log.debug("new font outline width: %d", new_font_outline_width)
|
356
344
|
return new_font_outline_width
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: fotolab
|
3
|
-
Version: 0.31.
|
3
|
+
Version: 0.31.4
|
4
4
|
Summary: A console program that manipulate images.
|
5
5
|
Keywords: photography,photo
|
6
6
|
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
18
18
|
Classifier: Programming Language :: Python
|
19
|
+
License-File: LICENSE.md
|
19
20
|
Requires-Dist: pillow
|
20
21
|
Project-URL: Changelog, https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
|
21
22
|
Project-URL: Issues, https://github.com/kianmeng/fotolab/issues
|
@@ -27,28 +28,22 @@ A console program to manipulate photos.
|
|
27
28
|
|
28
29
|
## Installation
|
29
30
|
|
30
|
-
Stable version From PyPI using `
|
31
|
+
Stable version From PyPI using `uv`:
|
31
32
|
|
32
33
|
```console
|
33
|
-
|
34
|
-
```
|
35
|
-
|
36
|
-
Stable version From PyPI using `pip`:
|
37
|
-
|
38
|
-
```console
|
39
|
-
python -m pip install fotolab
|
34
|
+
uv pip install fotolab
|
40
35
|
```
|
41
36
|
|
42
37
|
Upgrade to latest stable version:
|
43
38
|
|
44
39
|
```console
|
45
|
-
|
40
|
+
uv pip install fotolab --upgrade
|
46
41
|
```
|
47
42
|
|
48
43
|
Latest development version from GitHub:
|
49
44
|
|
50
45
|
```console
|
51
|
-
|
46
|
+
uv pip install -e git+https://github.com/kianmeng/fotolab.git
|
52
47
|
```
|
53
48
|
|
54
49
|
## Usage
|
@@ -0,0 +1,21 @@
|
|
1
|
+
fotolab/__init__.py,sha256=7XrkZPbYLVCnsak061vye7L9hFC7zj7cP7XWdjunAk8,3137
|
2
|
+
fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
|
3
|
+
fotolab/cli.py,sha256=oFiQXmsu3wIsM_DpZnL4B94sAoB62L16Am-cjxGmosY,4406
|
4
|
+
fotolab/subcommands/__init__.py,sha256=zPNE3lTK3yNjBq2zP1GiL13R4ywO_zh5MRFp5aOFp_g,1121
|
5
|
+
fotolab/subcommands/animate.py,sha256=Bzp1Y708UZogcLFwZSoJBfLAxLNZ5c0PESp1xl03sQg,5512
|
6
|
+
fotolab/subcommands/auto.py,sha256=3Hl1cCdu65GcfwvwiMRAcex6c7zA-KqIY6AFnB6nI3w,2447
|
7
|
+
fotolab/subcommands/border.py,sha256=3mD6ebdPjGk39ldUq9766jEXCbszPlbyV48k13dmrSA,4621
|
8
|
+
fotolab/subcommands/contrast.py,sha256=k-NGncYgm7x821CP-NhDbyZGzW1FPxaDgJi00xd97kw,2969
|
9
|
+
fotolab/subcommands/env.py,sha256=QoxRvzZKgmoHTUxDV4QYhdChCpMWs5TbXFY_qIpIQpE,1469
|
10
|
+
fotolab/subcommands/halftone.py,sha256=4YpHkp3zSYp36qJVPinWBOAUhTJjc-aGxiaNd1IkhXA,6655
|
11
|
+
fotolab/subcommands/info.py,sha256=pT2NBZ-KBjBCJJRpC9HC04iZj3s6RhbLWTRG6vjsarg,3549
|
12
|
+
fotolab/subcommands/montage.py,sha256=6-3VFMOQm3KOhcGaDfzStTKvBB5GHrotFkHU9kxZe5E,2552
|
13
|
+
fotolab/subcommands/resize.py,sha256=h4t425Xf95lkh6Trp-qw_cu0bBgMgBSBvJvUIR4dqiE,5407
|
14
|
+
fotolab/subcommands/rotate.py,sha256=uBFjHyjiBSQLtrtH1p9myODIHUDr1gkL4PpU-6Y1Ofo,2575
|
15
|
+
fotolab/subcommands/sharpen.py,sha256=YNho2IPbc-lPvSy3Bsjehc2JOEy27LPqFSGRULs9MyY,3492
|
16
|
+
fotolab/subcommands/watermark.py,sha256=uVcFynGt2hkTNF5RnfdHhBxSoLmlA7o8-_I65pe_di0,11166
|
17
|
+
fotolab-0.31.4.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
|
18
|
+
fotolab-0.31.4.dist-info/licenses/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
19
|
+
fotolab-0.31.4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
20
|
+
fotolab-0.31.4.dist-info/METADATA,sha256=gUG_1R0jrlUKYmjNF_HSQpLCOh71dnBwCzAF_KrFDos,13581
|
21
|
+
fotolab-0.31.4.dist-info/RECORD,,
|
fotolab-0.31.1.dist-info/RECORD
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
fotolab/__init__.py,sha256=KWNA2ZPAuWOJFMr7zE2Lqnp2yOIi8e7vNdeo9uanRsQ,3087
|
2
|
-
fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
|
3
|
-
fotolab/cli.py,sha256=oFiQXmsu3wIsM_DpZnL4B94sAoB62L16Am-cjxGmosY,4406
|
4
|
-
fotolab/subcommands/__init__.py,sha256=l3DlIaJ3u3jGjnC1H1yV8LZ_nPqOLJ6gikD4BCaMAQ0,1129
|
5
|
-
fotolab/subcommands/animate.py,sha256=_tfIJOcwft-OP1PluPThWMsO6RAunj5RbhxeRi8Gf9w,5549
|
6
|
-
fotolab/subcommands/auto.py,sha256=3Hl1cCdu65GcfwvwiMRAcex6c7zA-KqIY6AFnB6nI3w,2447
|
7
|
-
fotolab/subcommands/border.py,sha256=-RNAYVcVTVrySzkmu3bIf__FTzog1BFC1jXqozF7PVM,4695
|
8
|
-
fotolab/subcommands/contrast.py,sha256=fcXmHnxDw74j5ZUDQ5cwWh0N4tpyqqvEjymnpITgrEk,3027
|
9
|
-
fotolab/subcommands/env.py,sha256=QoxRvzZKgmoHTUxDV4QYhdChCpMWs5TbXFY_qIpIQpE,1469
|
10
|
-
fotolab/subcommands/halftone.py,sha256=lt6RV0OuZkGs1LigTC1EcCCY42CocPFHWaJTDjJ5LFM,6693
|
11
|
-
fotolab/subcommands/info.py,sha256=H3voMi67cKoHT2Mu4RUNQBPdb_MspetPjhOvy-YyNnE,3563
|
12
|
-
fotolab/subcommands/montage.py,sha256=d_3EcyRSFS8fKkczlHO8IRP-mrKhQUtkQndjfd0MKsc,2566
|
13
|
-
fotolab/subcommands/resize.py,sha256=UOb2rg_5ArRj0gxPTDOww_ix3tqJRC0W5b_S-Lt1G4w,5444
|
14
|
-
fotolab/subcommands/rotate.py,sha256=uBFjHyjiBSQLtrtH1p9myODIHUDr1gkL4PpU-6Y1Ofo,2575
|
15
|
-
fotolab/subcommands/sharpen.py,sha256=YNho2IPbc-lPvSy3Bsjehc2JOEy27LPqFSGRULs9MyY,3492
|
16
|
-
fotolab/subcommands/watermark.py,sha256=wKv_8eREUZ20hNF2xKs1XZlcSNbB2kdG_kbBlaXhJ1I,11298
|
17
|
-
fotolab-0.31.1.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
|
18
|
-
fotolab-0.31.1.dist-info/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
19
|
-
fotolab-0.31.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
20
|
-
fotolab-0.31.1.dist-info/METADATA,sha256=UjjTDVhNEU_PHEGJE-Cc_Z2zNugHVnxycHU3lzpBLIM,13656
|
21
|
-
fotolab-0.31.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|