fotolab 0.31.0__py3-none-any.whl → 0.31.1__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 +1 -1
- fotolab/subcommands/animate.py +13 -7
- fotolab/subcommands/auto.py +1 -0
- fotolab/subcommands/border.py +1 -1
- fotolab/subcommands/info.py +16 -22
- fotolab/subcommands/watermark.py +4 -4
- {fotolab-0.31.0.dist-info → fotolab-0.31.1.dist-info}/METADATA +7 -2
- {fotolab-0.31.0.dist-info → fotolab-0.31.1.dist-info}/RECORD +11 -11
- {fotolab-0.31.0.dist-info → fotolab-0.31.1.dist-info}/LICENSE.md +0 -0
- {fotolab-0.31.0.dist-info → fotolab-0.31.1.dist-info}/WHEEL +0 -0
- {fotolab-0.31.0.dist-info → fotolab-0.31.1.dist-info}/entry_points.txt +0 -0
fotolab/__init__.py
CHANGED
fotolab/subcommands/animate.py
CHANGED
@@ -73,7 +73,10 @@ def build_subparser(subparsers) -> None:
|
|
73
73
|
dest="duration",
|
74
74
|
type=_validate_duration,
|
75
75
|
default=2500,
|
76
|
-
help=
|
76
|
+
help=(
|
77
|
+
"set the duration in milliseconds "
|
78
|
+
"(must be a positive integer, default: '%(default)s')"
|
79
|
+
),
|
77
80
|
metavar="DURATION",
|
78
81
|
)
|
79
82
|
|
@@ -120,7 +123,10 @@ def build_subparser(subparsers) -> None:
|
|
120
123
|
type=int,
|
121
124
|
default=4,
|
122
125
|
choices=range(0, 7),
|
123
|
-
help=
|
126
|
+
help=(
|
127
|
+
"set WEBP encoding method "
|
128
|
+
"(0=fast, 6=slow/best, default: '%(default)s')"
|
129
|
+
),
|
124
130
|
metavar="METHOD",
|
125
131
|
)
|
126
132
|
|
@@ -170,17 +176,17 @@ def run(args: argparse.Namespace) -> None:
|
|
170
176
|
"save_all": True,
|
171
177
|
"duration": args.duration,
|
172
178
|
"loop": args.loop,
|
173
|
-
"optimize": True,
|
179
|
+
"optimize": True,
|
174
180
|
}
|
175
181
|
|
182
|
+
# Pillow's WEBP save doesn't use a general 'optimize' like GIF.
|
183
|
+
# Specific WEBP params like 'method' and 'quality' control this. We
|
184
|
+
# can remove 'optimize' if it causes issues or is ignored for WEBP.
|
185
|
+
# For now, let's keep it, Pillow might handle it or ignore it.
|
176
186
|
if args.format == "webp":
|
177
187
|
save_kwargs["quality"] = args.webp_quality
|
178
188
|
save_kwargs["lossless"] = args.webp_lossless
|
179
189
|
save_kwargs["method"] = args.webp_method
|
180
|
-
# Pillow's WEBP save doesn't use a general 'optimize' like GIF.
|
181
|
-
# Specific WEBP params like 'method' and 'quality' control this.
|
182
|
-
# We can remove 'optimize' if it causes issues or is ignored for WEBP.
|
183
|
-
# For now, let's keep it, Pillow might handle it or ignore it.
|
184
190
|
|
185
191
|
main_frame.save(new_filename, **save_kwargs)
|
186
192
|
finally:
|
fotolab/subcommands/auto.py
CHANGED
fotolab/subcommands/border.py
CHANGED
fotolab/subcommands/info.py
CHANGED
@@ -81,31 +81,25 @@ def run(args: argparse.Namespace) -> None:
|
|
81
81
|
return
|
82
82
|
|
83
83
|
output_info = []
|
84
|
-
specific_info_requested = False
|
85
84
|
|
86
|
-
|
87
|
-
|
88
|
-
output_info.append(camera_metadata(exif_tags))
|
85
|
+
if args.camera:
|
86
|
+
output_info.append(get_formatted_camera_info(exif_tags))
|
89
87
|
|
90
|
-
|
91
|
-
|
92
|
-
output_info.append(datetime(exif_tags))
|
88
|
+
if args.datetime:
|
89
|
+
output_info.append(get_formatted_datetime_info(exif_tags))
|
93
90
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
91
|
+
if output_info: # Check if any specific info was added
|
92
|
+
print("\n".join(output_info))
|
93
|
+
else:
|
94
|
+
# Print all tags if no specific info was requested
|
95
|
+
tag_name_width = max(map(len, exif_tags))
|
96
|
+
for tag_name, tag_value in exif_tags.items():
|
97
|
+
print(f"{tag_name:<{tag_name_width}}: {tag_value}")
|
101
98
|
|
102
99
|
|
103
100
|
def extract_exif_tags(image: Image.Image, sort: bool = False) -> dict:
|
104
101
|
"""Extract Exif metadata from image."""
|
105
|
-
|
106
|
-
exif = image._getexif()
|
107
|
-
except AttributeError:
|
108
|
-
exif = None
|
102
|
+
exif = image.getexif()
|
109
103
|
|
110
104
|
log.debug(exif)
|
111
105
|
|
@@ -122,13 +116,13 @@ def extract_exif_tags(image: Image.Image, sort: bool = False) -> dict:
|
|
122
116
|
return filtered_info
|
123
117
|
|
124
118
|
|
125
|
-
def
|
126
|
-
"""Extract datetime metadata."""
|
119
|
+
def get_formatted_datetime_info(exif_tags: dict):
|
120
|
+
"""Extract and format datetime metadata."""
|
127
121
|
return exif_tags.get("DateTime", "Not available")
|
128
122
|
|
129
123
|
|
130
|
-
def
|
131
|
-
"""Extract camera and model metadata."""
|
124
|
+
def get_formatted_camera_info(exif_tags: dict):
|
125
|
+
"""Extract and format camera make and model metadata."""
|
132
126
|
make = exif_tags.get("Make", "")
|
133
127
|
model = exif_tags.get("Model", "")
|
134
128
|
metadata = f"{make} {model}"
|
fotolab/subcommands/watermark.py
CHANGED
@@ -24,7 +24,7 @@ from typing import Tuple
|
|
24
24
|
from PIL import Image, ImageColor, ImageDraw, ImageFont, ImageSequence
|
25
25
|
|
26
26
|
from fotolab import save_image
|
27
|
-
from fotolab.subcommands.info import
|
27
|
+
from fotolab.subcommands.info import get_formatted_camera_info
|
28
28
|
|
29
29
|
log: logging.Logger = logging.getLogger(__name__)
|
30
30
|
|
@@ -312,10 +312,10 @@ def watermark_image(
|
|
312
312
|
|
313
313
|
def prepare_text(args: argparse.Namespace, image: Image.Image) -> str:
|
314
314
|
"""Prepare the watermark text."""
|
315
|
-
text
|
315
|
+
text = args.text
|
316
316
|
if args.camera:
|
317
|
-
metadata_text
|
318
|
-
if metadata_text:
|
317
|
+
metadata_text = get_formatted_camera_info(image)
|
318
|
+
if metadata_text:
|
319
319
|
text = metadata_text
|
320
320
|
else:
|
321
321
|
log.warning(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fotolab
|
3
|
-
Version: 0.31.
|
3
|
+
Version: 0.31.1
|
4
4
|
Summary: A console program that manipulate images.
|
5
5
|
Keywords: photography,photo
|
6
6
|
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
@@ -371,7 +371,8 @@ fotolab watermark -h
|
|
371
371
|
usage: fotolab watermark [-h] [-t WATERMARK_TEXT]
|
372
372
|
[-p {top-left,top-right,bottom-left,bottom-right}]
|
373
373
|
[-pd PADDING] [-fs FONT_SIZE] [-fc FONT_COLOR]
|
374
|
-
[-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR]
|
374
|
+
[-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR]
|
375
|
+
[-a ALPHA_VALUE] [--camera]
|
375
376
|
[-l | --lowercase | --no-lowercase] [-op]
|
376
377
|
[-od OUTPUT_DIR]
|
377
378
|
IMAGE_FILENAMES [IMAGE_FILENAMES ...]
|
@@ -400,6 +401,10 @@ options:
|
|
400
401
|
-oc, --outline-color OUTLINE_COLOR
|
401
402
|
set the outline color of the watermark text (default:
|
402
403
|
'black')
|
404
|
+
-a, --alpha ALPHA_VALUE
|
405
|
+
set the transparency of the watermark text (0-255,
|
406
|
+
where 0 is fully transparent and 255 is fully opaque;
|
407
|
+
default: '128')
|
403
408
|
--camera use camera metadata as watermark
|
404
409
|
-l, --lowercase, --no-lowercase
|
405
410
|
lowercase the watermark text
|
@@ -1,21 +1,21 @@
|
|
1
|
-
fotolab/__init__.py,sha256=
|
1
|
+
fotolab/__init__.py,sha256=KWNA2ZPAuWOJFMr7zE2Lqnp2yOIi8e7vNdeo9uanRsQ,3087
|
2
2
|
fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
|
3
3
|
fotolab/cli.py,sha256=oFiQXmsu3wIsM_DpZnL4B94sAoB62L16Am-cjxGmosY,4406
|
4
4
|
fotolab/subcommands/__init__.py,sha256=l3DlIaJ3u3jGjnC1H1yV8LZ_nPqOLJ6gikD4BCaMAQ0,1129
|
5
|
-
fotolab/subcommands/animate.py,sha256=
|
6
|
-
fotolab/subcommands/auto.py,sha256=
|
7
|
-
fotolab/subcommands/border.py,sha256
|
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
8
|
fotolab/subcommands/contrast.py,sha256=fcXmHnxDw74j5ZUDQ5cwWh0N4tpyqqvEjymnpITgrEk,3027
|
9
9
|
fotolab/subcommands/env.py,sha256=QoxRvzZKgmoHTUxDV4QYhdChCpMWs5TbXFY_qIpIQpE,1469
|
10
10
|
fotolab/subcommands/halftone.py,sha256=lt6RV0OuZkGs1LigTC1EcCCY42CocPFHWaJTDjJ5LFM,6693
|
11
|
-
fotolab/subcommands/info.py,sha256=
|
11
|
+
fotolab/subcommands/info.py,sha256=H3voMi67cKoHT2Mu4RUNQBPdb_MspetPjhOvy-YyNnE,3563
|
12
12
|
fotolab/subcommands/montage.py,sha256=d_3EcyRSFS8fKkczlHO8IRP-mrKhQUtkQndjfd0MKsc,2566
|
13
13
|
fotolab/subcommands/resize.py,sha256=UOb2rg_5ArRj0gxPTDOww_ix3tqJRC0W5b_S-Lt1G4w,5444
|
14
14
|
fotolab/subcommands/rotate.py,sha256=uBFjHyjiBSQLtrtH1p9myODIHUDr1gkL4PpU-6Y1Ofo,2575
|
15
15
|
fotolab/subcommands/sharpen.py,sha256=YNho2IPbc-lPvSy3Bsjehc2JOEy27LPqFSGRULs9MyY,3492
|
16
|
-
fotolab/subcommands/watermark.py,sha256=
|
17
|
-
fotolab-0.31.
|
18
|
-
fotolab-0.31.
|
19
|
-
fotolab-0.31.
|
20
|
-
fotolab-0.31.
|
21
|
-
fotolab-0.31.
|
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
|
File without changes
|