fotolab 0.31.16__py3-none-any.whl → 0.33.0__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 +35 -26
- fotolab/subcommands/animate.py +29 -14
- fotolab/subcommands/auto.py +44 -3
- fotolab/subcommands/border.py +4 -3
- fotolab/subcommands/contrast.py +2 -1
- fotolab/subcommands/halftone.py +6 -2
- fotolab/subcommands/montage.py +6 -4
- fotolab/subcommands/resize.py +4 -3
- fotolab/subcommands/rotate.py +9 -1
- fotolab/subcommands/sharpen.py +7 -2
- fotolab/subcommands/watermark.py +8 -4
- {fotolab-0.31.16.dist-info → fotolab-0.33.0.dist-info}/METADATA +15 -1
- fotolab-0.33.0.dist-info/RECORD +22 -0
- fotolab-0.31.16.dist-info/RECORD +0 -22
- {fotolab-0.31.16.dist-info → fotolab-0.33.0.dist-info}/WHEEL +0 -0
- {fotolab-0.31.16.dist-info → fotolab-0.33.0.dist-info}/entry_points.txt +0 -0
- {fotolab-0.31.16.dist-info → fotolab-0.33.0.dist-info}/licenses/LICENSE.md +0 -0
- {fotolab-0.31.16.dist-info → fotolab-0.33.0.dist-info}/top_level.txt +0 -0
fotolab/__init__.py
CHANGED
@@ -31,30 +31,45 @@ log = logging.getLogger(__name__)
|
|
31
31
|
|
32
32
|
def save_gif_image(
|
33
33
|
args: argparse.Namespace,
|
34
|
-
|
34
|
+
image_filepath: Path,
|
35
35
|
original_image: Image.Image,
|
36
36
|
after_image: Image.Image,
|
37
37
|
subcommand: str,
|
38
38
|
) -> None:
|
39
39
|
"""Save the original and after image."""
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
format="gif",
|
51
|
-
append_images=[after_image],
|
52
|
-
save_all=True,
|
53
|
-
duration=2500,
|
54
|
-
loop=0,
|
55
|
-
optimize=True,
|
40
|
+
gif_kwargs = {
|
41
|
+
"format": "gif",
|
42
|
+
"append_images": [after_image],
|
43
|
+
"save_all": True,
|
44
|
+
"duration": 2500,
|
45
|
+
"loop": 0,
|
46
|
+
"optimize": True,
|
47
|
+
}
|
48
|
+
_save_image_with_options(
|
49
|
+
args, original_image, image_filepath, subcommand, **gif_kwargs
|
56
50
|
)
|
57
51
|
|
52
|
+
|
53
|
+
def _save_image_with_options(
|
54
|
+
args: argparse.Namespace,
|
55
|
+
image: Image.Image,
|
56
|
+
output_filepath: Path,
|
57
|
+
subcommand: str,
|
58
|
+
**kwargs,
|
59
|
+
) -> None:
|
60
|
+
"""Save image with additional options and handle opening.
|
61
|
+
|
62
|
+
Args:
|
63
|
+
args (argparse.Namespace): Config from command line arguments.
|
64
|
+
image (Image.Image): The image to save.
|
65
|
+
output_filepath (Path): The path to save the image to.
|
66
|
+
subcommand (str): The name of the subcommand.
|
67
|
+
**kwargs: Additional keyword arguments for Image.save().
|
68
|
+
"""
|
69
|
+
new_filename = _get_output_filename(args, output_filepath, subcommand)
|
70
|
+
log.info("%s image: %s", subcommand, new_filename.resolve())
|
71
|
+
image.save(new_filename, **kwargs)
|
72
|
+
|
58
73
|
if args.open:
|
59
74
|
_open_image(new_filename)
|
60
75
|
|
@@ -62,7 +77,7 @@ def save_gif_image(
|
|
62
77
|
def save_image(
|
63
78
|
args: argparse.Namespace,
|
64
79
|
new_image: Image.Image,
|
65
|
-
|
80
|
+
output_filepath: Path,
|
66
81
|
subcommand: str,
|
67
82
|
) -> None:
|
68
83
|
"""Save image after image operation.
|
@@ -70,13 +85,7 @@ def save_image(
|
|
70
85
|
Returns:
|
71
86
|
None
|
72
87
|
"""
|
73
|
-
|
74
|
-
new_filename = _get_output_filename(args, image_file, subcommand)
|
75
|
-
log.info("%s image: %s", subcommand, new_filename.resolve())
|
76
|
-
new_image.save(new_filename)
|
77
|
-
|
78
|
-
if args.open:
|
79
|
-
_open_image(new_filename)
|
88
|
+
_save_image_with_options(args, new_image, output_filepath, subcommand)
|
80
89
|
|
81
90
|
|
82
91
|
def _get_output_filename(
|
@@ -91,7 +100,7 @@ def _get_output_filename(
|
|
91
100
|
return output_dir / image_file.with_name(f"{subcommand}_{image_file.name}")
|
92
101
|
|
93
102
|
|
94
|
-
def _open_image(filename):
|
103
|
+
def _open_image(filename: Path):
|
95
104
|
"""Open generated image using default program."""
|
96
105
|
try:
|
97
106
|
if sys.platform == "linux":
|
fotolab/subcommands/animate.py
CHANGED
@@ -125,7 +125,8 @@ def build_subparser(subparsers) -> None:
|
|
125
125
|
default=4,
|
126
126
|
choices=range(0, 7),
|
127
127
|
help=(
|
128
|
-
"set WEBP encoding method
|
128
|
+
"set WEBP encoding method "
|
129
|
+
"(0=fast, 6=slow/best, default: '%(default)s')"
|
129
130
|
),
|
130
131
|
metavar="METHOD",
|
131
132
|
)
|
@@ -138,6 +139,14 @@ def build_subparser(subparsers) -> None:
|
|
138
139
|
help="set default output folder (default: '%(default)s')",
|
139
140
|
)
|
140
141
|
|
142
|
+
animate_parser.add_argument(
|
143
|
+
"-of",
|
144
|
+
"--output-filename",
|
145
|
+
dest="output_filename",
|
146
|
+
default=None,
|
147
|
+
help="set output filename (default: '%(default)s')",
|
148
|
+
)
|
149
|
+
|
141
150
|
|
142
151
|
def run(args: argparse.Namespace) -> None:
|
143
152
|
"""Run animate subcommand.
|
@@ -150,21 +159,27 @@ def run(args: argparse.Namespace) -> None:
|
|
150
159
|
"""
|
151
160
|
log.debug(args)
|
152
161
|
|
153
|
-
|
162
|
+
image_filepaths = [Path(f) for f in args.image_filenames]
|
163
|
+
first_image_filepath = image_filepaths[0]
|
154
164
|
other_frames = []
|
155
165
|
|
156
166
|
with ExitStack() as stack:
|
157
167
|
main_frame = stack.enter_context(Image.open(first_image_filepath))
|
158
168
|
|
159
|
-
for
|
160
|
-
img = stack.enter_context(Image.open(
|
169
|
+
for image_filepath in image_filepaths[1:]:
|
170
|
+
img = stack.enter_context(Image.open(image_filepath))
|
161
171
|
other_frames.append(img)
|
162
172
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
image_file
|
167
|
-
|
173
|
+
if args.output_filename:
|
174
|
+
new_filename = Path(args.output_dir, args.output_filename)
|
175
|
+
else:
|
176
|
+
image_file = Path(first_image_filepath)
|
177
|
+
new_filename = Path(
|
178
|
+
args.output_dir,
|
179
|
+
image_file.with_name(
|
180
|
+
f"animate_{image_file.stem}.{args.format}"
|
181
|
+
),
|
182
|
+
)
|
168
183
|
new_filename.parent.mkdir(parents=True, exist_ok=True)
|
169
184
|
|
170
185
|
log.info("animate image: %s", new_filename)
|
@@ -175,14 +190,14 @@ def run(args: argparse.Namespace) -> None:
|
|
175
190
|
"save_all": True,
|
176
191
|
"duration": args.duration,
|
177
192
|
"loop": args.loop,
|
178
|
-
"optimize": True,
|
179
193
|
}
|
180
194
|
|
181
195
|
# Pillow's WEBP save doesn't use a general 'optimize' like GIF.
|
182
|
-
# Specific WEBP params like 'method' and 'quality' control this.
|
183
|
-
#
|
184
|
-
|
185
|
-
|
196
|
+
# Specific WEBP params like 'method' and 'quality' control this.
|
197
|
+
# 'optimize' is removed for WEBP to avoid confusion.
|
198
|
+
if args.format == "gif":
|
199
|
+
save_kwargs["optimize"] = True
|
200
|
+
elif args.format == "webp":
|
186
201
|
save_kwargs["quality"] = args.webp_quality
|
187
202
|
save_kwargs["lossless"] = args.webp_lossless
|
188
203
|
save_kwargs["method"] = args.webp_method
|
fotolab/subcommands/auto.py
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
20
|
|
21
|
+
import fotolab.subcommands.animate
|
21
22
|
import fotolab.subcommands.contrast
|
22
23
|
import fotolab.subcommands.resize
|
23
24
|
import fotolab.subcommands.sharpen
|
@@ -43,6 +44,26 @@ def build_subparser(subparsers) -> None:
|
|
43
44
|
metavar="IMAGE_FILENAMES",
|
44
45
|
)
|
45
46
|
|
47
|
+
auto_parser.add_argument(
|
48
|
+
"-t",
|
49
|
+
"--title",
|
50
|
+
dest="title",
|
51
|
+
help="set the tile (default: '%(default)s')",
|
52
|
+
type=str,
|
53
|
+
default=None,
|
54
|
+
metavar="TITLE",
|
55
|
+
)
|
56
|
+
|
57
|
+
auto_parser.add_argument(
|
58
|
+
"-w",
|
59
|
+
"--watermark",
|
60
|
+
dest="watermark",
|
61
|
+
help="set the watermark (default: '%(default)s')",
|
62
|
+
type=str,
|
63
|
+
default="kianmeng.org",
|
64
|
+
metavar="WATERMARK_TEXT",
|
65
|
+
)
|
66
|
+
|
46
67
|
|
47
68
|
def run(args: argparse.Namespace) -> None:
|
48
69
|
"""Run auto subcommand.
|
@@ -53,6 +74,10 @@ def run(args: argparse.Namespace) -> None:
|
|
53
74
|
Returns:
|
54
75
|
None
|
55
76
|
"""
|
77
|
+
text = args.watermark
|
78
|
+
if args.title and args.watermark:
|
79
|
+
text = f"{args.title}\n{args.watermark}"
|
80
|
+
|
56
81
|
extra_args = {
|
57
82
|
"width": 600,
|
58
83
|
"height": 277,
|
@@ -60,7 +85,7 @@ def run(args: argparse.Namespace) -> None:
|
|
60
85
|
"radius": 1,
|
61
86
|
"percent": 100,
|
62
87
|
"threshold": 2,
|
63
|
-
"text":
|
88
|
+
"text": text,
|
64
89
|
"position": "bottom-left",
|
65
90
|
"font_size": 12,
|
66
91
|
"font_color": "white",
|
@@ -69,13 +94,18 @@ def run(args: argparse.Namespace) -> None:
|
|
69
94
|
"padding": 15,
|
70
95
|
"camera": False,
|
71
96
|
"canvas": False,
|
72
|
-
"lowercase":
|
97
|
+
"lowercase": True,
|
73
98
|
"before_after": False,
|
74
99
|
"alpha": 128,
|
75
100
|
}
|
76
|
-
|
101
|
+
|
102
|
+
# resolve error: argparse.Namespace() got multiple values for keyword
|
103
|
+
# argument 'text'
|
104
|
+
merged_args = {**vars(args), **extra_args}
|
105
|
+
combined_args = argparse.Namespace(**merged_args)
|
77
106
|
combined_args.overwrite = True
|
78
107
|
combined_args.open = False
|
108
|
+
|
79
109
|
log.debug(args)
|
80
110
|
log.debug(combined_args)
|
81
111
|
|
@@ -83,3 +113,14 @@ def run(args: argparse.Namespace) -> None:
|
|
83
113
|
fotolab.subcommands.contrast.run(combined_args)
|
84
114
|
fotolab.subcommands.sharpen.run(combined_args)
|
85
115
|
fotolab.subcommands.watermark.run(combined_args)
|
116
|
+
|
117
|
+
if len(args.image_filenames) > 1:
|
118
|
+
output_filename = (
|
119
|
+
args.title.lower().replace(",", "").replace(" ", "_") + ".gif"
|
120
|
+
)
|
121
|
+
combined_args.output_dir = "output"
|
122
|
+
combined_args.format = "gif"
|
123
|
+
combined_args.duration = 2500
|
124
|
+
combined_args.loop = 0
|
125
|
+
combined_args.output_filename = output_filename
|
126
|
+
fotolab.subcommands.animate.run(combined_args)
|
fotolab/subcommands/border.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
|
+
from pathlib import Path
|
20
21
|
from typing import Tuple
|
21
22
|
|
22
23
|
from PIL import Image, ImageColor, ImageOps
|
@@ -134,8 +135,8 @@ def run(args: argparse.Namespace) -> None:
|
|
134
135
|
"""
|
135
136
|
log.debug(args)
|
136
137
|
|
137
|
-
for
|
138
|
-
original_image = Image.open(
|
138
|
+
for image_filepath in [Path(f) for f in args.image_filenames]:
|
139
|
+
original_image = Image.open(image_filepath)
|
139
140
|
border = get_border(args)
|
140
141
|
bordered_image = ImageOps.expand(
|
141
142
|
original_image,
|
@@ -143,7 +144,7 @@ def run(args: argparse.Namespace) -> None:
|
|
143
144
|
fill=ImageColor.getrgb(args.color),
|
144
145
|
)
|
145
146
|
|
146
|
-
save_image(args, bordered_image,
|
147
|
+
save_image(args, bordered_image, image_filepath, "border")
|
147
148
|
|
148
149
|
|
149
150
|
def get_border(
|
fotolab/subcommands/contrast.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
|
+
from pathlib import Path
|
20
21
|
|
21
22
|
from PIL import Image, ImageOps
|
22
23
|
|
@@ -107,4 +108,4 @@ def run(args: argparse.Namespace) -> None:
|
|
107
108
|
original_image, cutoff=args.cutoff
|
108
109
|
)
|
109
110
|
|
110
|
-
save_image(args, contrast_image, image_filename, "contrast")
|
111
|
+
save_image(args, contrast_image, Path(image_filename), "contrast")
|
fotolab/subcommands/halftone.py
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
20
|
import math
|
21
|
+
from pathlib import Path
|
21
22
|
from typing import NamedTuple, Union
|
22
23
|
|
23
24
|
from PIL import Image, ImageDraw
|
@@ -84,7 +85,9 @@ def build_subparser(subparsers) -> None:
|
|
84
85
|
dest="cells",
|
85
86
|
type=int,
|
86
87
|
default=50,
|
87
|
-
help=
|
88
|
+
help=(
|
89
|
+
"set number of cells across the image width (default: %(default)s)"
|
90
|
+
),
|
88
91
|
)
|
89
92
|
|
90
93
|
halftone_parser.add_argument(
|
@@ -108,7 +111,8 @@ def run(args: argparse.Namespace) -> None:
|
|
108
111
|
"""
|
109
112
|
log.debug(args)
|
110
113
|
|
111
|
-
for
|
114
|
+
for image_filename_str in args.image_filenames:
|
115
|
+
image_filename = Path(image_filename_str)
|
112
116
|
original_image = Image.open(image_filename)
|
113
117
|
halftone_image = create_halftone_image(
|
114
118
|
original_image, args.cells, args.grayscale
|
fotolab/subcommands/montage.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
|
+
from pathlib import Path
|
20
21
|
|
21
22
|
from PIL import Image
|
22
23
|
|
@@ -37,7 +38,7 @@ def build_subparser(subparsers) -> None:
|
|
37
38
|
dest="image_filenames",
|
38
39
|
help="set the image filenames",
|
39
40
|
nargs="+",
|
40
|
-
type=
|
41
|
+
type=str,
|
41
42
|
default=None,
|
42
43
|
metavar="IMAGE_FILENAMES",
|
43
44
|
)
|
@@ -71,8 +72,9 @@ def run(args: argparse.Namespace) -> None:
|
|
71
72
|
"""
|
72
73
|
log.debug(args)
|
73
74
|
images = []
|
74
|
-
for
|
75
|
-
|
75
|
+
for image_filename_str in args.image_filenames:
|
76
|
+
image_filename = Path(image_filename_str)
|
77
|
+
images.append(Image.open(image_filename))
|
76
78
|
|
77
79
|
if len(images) < 2:
|
78
80
|
raise ValueError("at least two images is required for montage")
|
@@ -87,5 +89,5 @@ def run(args: argparse.Namespace) -> None:
|
|
87
89
|
montaged_image.paste(image, (x_offset, 0))
|
88
90
|
x_offset += image.width
|
89
91
|
|
90
|
-
output_image_filename = args.image_filenames[0]
|
92
|
+
output_image_filename = Path(args.image_filenames[0])
|
91
93
|
save_image(args, montaged_image, output_image_filename, "montage")
|
fotolab/subcommands/resize.py
CHANGED
@@ -19,6 +19,7 @@ import argparse
|
|
19
19
|
import logging
|
20
20
|
import math
|
21
21
|
import sys
|
22
|
+
from pathlib import Path
|
22
23
|
|
23
24
|
from PIL import Image, ImageColor
|
24
25
|
|
@@ -136,13 +137,13 @@ def run(args: argparse.Namespace) -> None:
|
|
136
137
|
"""
|
137
138
|
log.debug(args)
|
138
139
|
|
139
|
-
for
|
140
|
-
original_image = Image.open(
|
140
|
+
for image_filepath in [Path(f) for f in args.image_filenames]:
|
141
|
+
original_image = Image.open(image_filepath)
|
141
142
|
if args.canvas:
|
142
143
|
resized_image = _resize_image_onto_canvas(original_image, args)
|
143
144
|
else:
|
144
145
|
resized_image = _resize_image(original_image, args)
|
145
|
-
save_image(args, resized_image,
|
146
|
+
save_image(args, resized_image, image_filepath, "resize")
|
146
147
|
|
147
148
|
|
148
149
|
def _resize_image_onto_canvas(original_image, args):
|
fotolab/subcommands/rotate.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
|
+
from pathlib import Path
|
20
21
|
|
21
22
|
from PIL import Image
|
22
23
|
|
@@ -85,9 +86,16 @@ def run(args: argparse.Namespace) -> None:
|
|
85
86
|
log.debug(args)
|
86
87
|
|
87
88
|
rotation = -args.rotation if args.clockwise else args.rotation
|
88
|
-
|
89
|
+
log.debug(f"Rotation angle: {rotation} degrees")
|
90
|
+
|
91
|
+
for image_filename_str in args.image_filenames:
|
92
|
+
image_filename = Path(image_filename_str)
|
93
|
+
log.debug(f"Processing image: {image_filename}")
|
89
94
|
original_image = Image.open(image_filename)
|
95
|
+
log.debug(f"Original image size: {original_image.size}")
|
90
96
|
rotated_image = original_image.rotate(
|
91
97
|
rotation, expand=True, resample=Image.Resampling.BICUBIC
|
92
98
|
)
|
99
|
+
log.debug(f"Rotated image size: {rotated_image.size}")
|
93
100
|
save_image(args, rotated_image, image_filename, "rotate")
|
101
|
+
log.debug(f"Image saved: {image_filename}")
|
fotolab/subcommands/sharpen.py
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
|
18
18
|
import argparse
|
19
19
|
import logging
|
20
|
+
from pathlib import Path
|
20
21
|
|
21
22
|
from PIL import Image, ImageFilter
|
22
23
|
|
@@ -123,7 +124,11 @@ def run(args: argparse.Namespace) -> None:
|
|
123
124
|
)
|
124
125
|
if args.before_after:
|
125
126
|
save_gif_image(
|
126
|
-
args,
|
127
|
+
args,
|
128
|
+
Path(image_filename),
|
129
|
+
original_image,
|
130
|
+
sharpen_image,
|
131
|
+
"sharpen",
|
127
132
|
)
|
128
133
|
else:
|
129
|
-
save_image(args, sharpen_image, image_filename, "sharpen")
|
134
|
+
save_image(args, sharpen_image, Path(image_filename), "sharpen")
|
fotolab/subcommands/watermark.py
CHANGED
@@ -110,7 +110,8 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
110
110
|
type=int,
|
111
111
|
default=2,
|
112
112
|
help=(
|
113
|
-
"set the outline width of the watermark text
|
113
|
+
"set the outline width of the watermark text "
|
114
|
+
"(default: '%(default)s')"
|
114
115
|
),
|
115
116
|
metavar="OUTLINE_WIDTH",
|
116
117
|
)
|
@@ -122,7 +123,8 @@ def build_subparser(subparsers: argparse._SubParsersAction) -> None:
|
|
122
123
|
type=str,
|
123
124
|
default="black",
|
124
125
|
help=(
|
125
|
-
"set the outline color of the watermark text
|
126
|
+
"set the outline color of the watermark text "
|
127
|
+
"(default: '%(default)s')"
|
126
128
|
),
|
127
129
|
metavar="OUTLINE_COLOR",
|
128
130
|
)
|
@@ -204,7 +206,9 @@ def run(args: argparse.Namespace) -> None:
|
|
204
206
|
watermarked_image: Image.Image = watermark_non_gif_image(
|
205
207
|
image, args
|
206
208
|
)
|
207
|
-
save_image(
|
209
|
+
save_image(
|
210
|
+
args, watermarked_image, Path(image_filename), "watermark"
|
211
|
+
)
|
208
212
|
|
209
213
|
|
210
214
|
def watermark_gif_image(
|
@@ -325,7 +329,7 @@ def prepare_text(args: argparse.Namespace, image: Image.Image) -> str:
|
|
325
329
|
if args.lowercase:
|
326
330
|
text = text.lower()
|
327
331
|
|
328
|
-
return text
|
332
|
+
return text.replace("\\n", "\n")
|
329
333
|
|
330
334
|
|
331
335
|
def calc_font_size(image: Image.Image, args: argparse.Namespace) -> int:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fotolab
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.33.0
|
4
4
|
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
5
5
|
License-Expression: AGPL-3.0-or-later
|
6
6
|
Project-URL: Changelog, https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
|
@@ -20,6 +20,20 @@ Requires-Python: >=3.9
|
|
20
20
|
Description-Content-Type: text/markdown
|
21
21
|
License-File: LICENSE.md
|
22
22
|
Requires-Dist: pillow
|
23
|
+
Provides-Extra: test
|
24
|
+
Requires-Dist: pytest; extra == "test"
|
25
|
+
Requires-Dist: pytest-cov; extra == "test"
|
26
|
+
Requires-Dist: pytest-randomly; extra == "test"
|
27
|
+
Requires-Dist: pytest-xdist; extra == "test"
|
28
|
+
Requires-Dist: scripttest; extra == "test"
|
29
|
+
Provides-Extra: doc
|
30
|
+
Requires-Dist: myst-parser; extra == "doc"
|
31
|
+
Requires-Dist: sphinx; extra == "doc"
|
32
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == "doc"
|
33
|
+
Requires-Dist: sphinx-copybutton; extra == "doc"
|
34
|
+
Provides-Extra: lint
|
35
|
+
Requires-Dist: pre-commit; extra == "lint"
|
36
|
+
Requires-Dist: ruff; extra == "lint"
|
23
37
|
Dynamic: license-file
|
24
38
|
|
25
39
|
# fotolab
|
@@ -0,0 +1,22 @@
|
|
1
|
+
fotolab/__init__.py,sha256=Wb9aauJu-aXInocnVSuzUwpWoMSC6moNLQ1dLORbEgQ,3442
|
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=iEor831HVQtQ04Y2-kHxnU4--BfS75mXggVIblxrO6g,5881
|
6
|
+
fotolab/subcommands/auto.py,sha256=gkpZ15JwzSlQPYSqGSeeGu0SLKps3A2cEn1dYpyQEyk,3584
|
7
|
+
fotolab/subcommands/border.py,sha256=TSr1rqAPWe1ZThkZan_WiMQdSTuua2YPXg6fYcvFitQ,4715
|
8
|
+
fotolab/subcommands/contrast.py,sha256=1RD3B-7NTIReMvACmb_FQtLxx_RZdmpqKmvsEuYjy2Y,3058
|
9
|
+
fotolab/subcommands/env.py,sha256=QoxRvzZKgmoHTUxDV4QYhdChCpMWs5TbXFY_qIpIQpE,1469
|
10
|
+
fotolab/subcommands/halftone.py,sha256=56RRkyIhCyc6MPBujV2PIbuR9HobuFhqVQaq58A5ivQ,6781
|
11
|
+
fotolab/subcommands/info.py,sha256=H3voMi67cKoHT2Mu4RUNQBPdb_MspetPjhOvy-YyNnE,3563
|
12
|
+
fotolab/subcommands/montage.py,sha256=ax-TG5FixBRFHPGkVTq8kOtRL900K6nujeBYHZ0yBAE,2622
|
13
|
+
fotolab/subcommands/resize.py,sha256=dMjgy52zrCIYpuvdOHyoP46X-jBolXNi0PLIQ-0x7eE,5473
|
14
|
+
fotolab/subcommands/rotate.py,sha256=-yZ7pNW7PDOPBWbKPDut9z8bBe1NocfVBV_6V6tqq-4,2945
|
15
|
+
fotolab/subcommands/sharpen.py,sha256=vGBJHHHUaQ2_SHS-E1mHfNVIfnnNYcCk5ritajWTik8,3594
|
16
|
+
fotolab/subcommands/watermark.py,sha256=BkUa1tH86Ii_u03ypj9Tm0u9v7s9y9Jiz3aLpjmFDb8,11355
|
17
|
+
fotolab-0.33.0.dist-info/licenses/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
18
|
+
fotolab-0.33.0.dist-info/METADATA,sha256=T9V46riOT9o4ZsKI4gmTaxJ7VgdDVzvNo5YqTEnasfs,14765
|
19
|
+
fotolab-0.33.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
+
fotolab-0.33.0.dist-info/entry_points.txt,sha256=0e1go9plFpqj5FP-OpV2acxTAx3ViI59PMXuhejvgcQ,45
|
21
|
+
fotolab-0.33.0.dist-info/top_level.txt,sha256=XUJ3gdpsbjohoZCLdVlbQrxAUDkbQg7WwGQG2DaN0t4,8
|
22
|
+
fotolab-0.33.0.dist-info/RECORD,,
|
fotolab-0.31.16.dist-info/RECORD
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
fotolab/__init__.py,sha256=F1sYdgd88MdxeT60olYsMzaMY7EipL8lJlL44BuFYj4,3088
|
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=t1F0ekbYWVlQcCtnwsW_gsWjkFdGDqcr4R8VUztUuzI,5481
|
6
|
-
fotolab/subcommands/auto.py,sha256=3Hl1cCdu65GcfwvwiMRAcex6c7zA-KqIY6AFnB6nI3w,2447
|
7
|
-
fotolab/subcommands/border.py,sha256=VYs8SorNYMwk7bVhD7jyolvFly7XdV-s9tNVQQYZPtA,4671
|
8
|
-
fotolab/subcommands/contrast.py,sha256=fcXmHnxDw74j5ZUDQ5cwWh0N4tpyqqvEjymnpITgrEk,3027
|
9
|
-
fotolab/subcommands/env.py,sha256=QoxRvzZKgmoHTUxDV4QYhdChCpMWs5TbXFY_qIpIQpE,1469
|
10
|
-
fotolab/subcommands/halftone.py,sha256=PgTGf9cChCYYbhB6vdNmzndobb4sK36ujGtZz4XAma0,6678
|
11
|
-
fotolab/subcommands/info.py,sha256=H3voMi67cKoHT2Mu4RUNQBPdb_MspetPjhOvy-YyNnE,3563
|
12
|
-
fotolab/subcommands/montage.py,sha256=ouwOnJQeXJTzsXi-4uby8c6k_VWg0Yo37FuvwAFx8ME,2566
|
13
|
-
fotolab/subcommands/resize.py,sha256=eZGoHVMehpHrAX_y-M56s43lSvWmywMjHRVI_dYqpcA,5429
|
14
|
-
fotolab/subcommands/rotate.py,sha256=uBFjHyjiBSQLtrtH1p9myODIHUDr1gkL4PpU-6Y1Ofo,2575
|
15
|
-
fotolab/subcommands/sharpen.py,sha256=YNho2IPbc-lPvSy3Bsjehc2JOEy27LPqFSGRULs9MyY,3492
|
16
|
-
fotolab/subcommands/watermark.py,sha256=cpdzmdzBXcaXWSrklYycnkPLjorLnTM-IXjPigPu0y0,11268
|
17
|
-
fotolab-0.31.16.dist-info/licenses/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
18
|
-
fotolab-0.31.16.dist-info/METADATA,sha256=8jKYLTQsusRg8jCG1Qrpm7_2APnnx-AZDT5YOboU-Io,14220
|
19
|
-
fotolab-0.31.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
-
fotolab-0.31.16.dist-info/entry_points.txt,sha256=0e1go9plFpqj5FP-OpV2acxTAx3ViI59PMXuhejvgcQ,45
|
21
|
-
fotolab-0.31.16.dist-info/top_level.txt,sha256=XUJ3gdpsbjohoZCLdVlbQrxAUDkbQg7WwGQG2DaN0t4,8
|
22
|
-
fotolab-0.31.16.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|