fotolab 0.32.0__py3-none-any.whl → 0.33.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 +35 -26
- fotolab/subcommands/animate.py +29 -14
- fotolab/subcommands/auto.py +30 -4
- 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 +18 -17
- fotolab/subcommands/rotate.py +9 -1
- fotolab/subcommands/sharpen.py +7 -2
- fotolab/subcommands/watermark.py +3 -1
- {fotolab-0.32.0.dist-info → fotolab-0.33.1.dist-info}/METADATA +1 -1
- fotolab-0.33.1.dist-info/RECORD +22 -0
- fotolab-0.32.0.dist-info/RECORD +0 -22
- {fotolab-0.32.0.dist-info → fotolab-0.33.1.dist-info}/WHEEL +0 -0
- {fotolab-0.32.0.dist-info → fotolab-0.33.1.dist-info}/entry_points.txt +0 -0
- {fotolab-0.32.0.dist-info → fotolab-0.33.1.dist-info}/licenses/LICENSE.md +0 -0
- {fotolab-0.32.0.dist-info → fotolab-0.33.1.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
|
@@ -45,9 +46,19 @@ def build_subparser(subparsers) -> None:
|
|
45
46
|
|
46
47
|
auto_parser.add_argument(
|
47
48
|
"-t",
|
48
|
-
"--
|
49
|
-
dest="
|
50
|
-
help="set the
|
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')",
|
51
62
|
type=str,
|
52
63
|
default="kianmeng.org",
|
53
64
|
metavar="WATERMARK_TEXT",
|
@@ -63,6 +74,10 @@ def run(args: argparse.Namespace) -> None:
|
|
63
74
|
Returns:
|
64
75
|
None
|
65
76
|
"""
|
77
|
+
text = args.watermark
|
78
|
+
if args.title and args.watermark:
|
79
|
+
text = f"{args.title}\n{args.watermark}"
|
80
|
+
|
66
81
|
extra_args = {
|
67
82
|
"width": 600,
|
68
83
|
"height": 277,
|
@@ -70,7 +85,7 @@ def run(args: argparse.Namespace) -> None:
|
|
70
85
|
"radius": 1,
|
71
86
|
"percent": 100,
|
72
87
|
"threshold": 2,
|
73
|
-
"text":
|
88
|
+
"text": text,
|
74
89
|
"position": "bottom-left",
|
75
90
|
"font_size": 12,
|
76
91
|
"font_color": "white",
|
@@ -98,3 +113,14 @@ def run(args: argparse.Namespace) -> None:
|
|
98
113
|
fotolab.subcommands.contrast.run(combined_args)
|
99
114
|
fotolab.subcommands.sharpen.run(combined_args)
|
100
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):
|
@@ -167,26 +168,26 @@ def _resize_image(original_image, args):
|
|
167
168
|
|
168
169
|
|
169
170
|
def _calc_new_image_dimension(image, args) -> tuple:
|
170
|
-
new_width = args.width
|
171
|
-
new_height = args.height
|
172
|
-
|
173
171
|
old_width, old_height = image.size
|
174
172
|
log.debug("old image dimension: %d x %d", old_width, old_height)
|
175
173
|
|
176
|
-
|
177
|
-
|
178
|
-
log.debug("aspect ratio: %f", aspect_ratio)
|
174
|
+
new_width = args.width
|
175
|
+
new_height = args.height
|
179
176
|
|
180
|
-
|
181
|
-
log.debug("new height: %d", new_height)
|
177
|
+
original_aspect_ratio = old_width / old_height
|
182
178
|
|
183
|
-
if
|
184
|
-
|
185
|
-
|
179
|
+
if new_width != DEFAULT_WIDTH and new_height == DEFAULT_HEIGHT:
|
180
|
+
# user provided width, calculate height to maintain aspect ratio
|
181
|
+
new_height = math.ceil(new_width / original_aspect_ratio)
|
182
|
+
log.debug("new height calculated based on width: %d", new_height)
|
183
|
+
elif new_height != DEFAULT_HEIGHT and new_width == DEFAULT_WIDTH:
|
184
|
+
# user provided height, calculate width to maintain aspect ratio
|
185
|
+
new_width = math.ceil(new_height * original_aspect_ratio)
|
186
|
+
log.debug("new width calculated based on height: %d", new_width)
|
186
187
|
|
187
|
-
|
188
|
-
|
188
|
+
# if both are default, no calculation needed, use defaults
|
189
|
+
# due to argparse's mutually exclusive group, it's not possible for both
|
190
|
+
# new_width and new_height to be non-default when --canvas is False
|
189
191
|
|
190
192
|
log.debug("new image dimension: %d x %d", new_width, new_height)
|
191
|
-
|
192
193
|
return (new_width, new_height)
|
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
@@ -206,7 +206,9 @@ def run(args: argparse.Namespace) -> None:
|
|
206
206
|
watermarked_image: Image.Image = watermark_non_gif_image(
|
207
207
|
image, args
|
208
208
|
)
|
209
|
-
save_image(
|
209
|
+
save_image(
|
210
|
+
args, watermarked_image, Path(image_filename), "watermark"
|
211
|
+
)
|
210
212
|
|
211
213
|
|
212
214
|
def watermark_gif_image(
|
@@ -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=d1-_xoTB8Vf62bm7H_9MfXrMaJhlzLiUbePgTdYzaKs,5816
|
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.1.dist-info/licenses/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
18
|
+
fotolab-0.33.1.dist-info/METADATA,sha256=ZtAGsATHK5aXwOeCLN2x_nTYrIq-O1duinmONnfCHxo,14765
|
19
|
+
fotolab-0.33.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
+
fotolab-0.33.1.dist-info/entry_points.txt,sha256=0e1go9plFpqj5FP-OpV2acxTAx3ViI59PMXuhejvgcQ,45
|
21
|
+
fotolab-0.33.1.dist-info/top_level.txt,sha256=XUJ3gdpsbjohoZCLdVlbQrxAUDkbQg7WwGQG2DaN0t4,8
|
22
|
+
fotolab-0.33.1.dist-info/RECORD,,
|
fotolab-0.32.0.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=8QXSCd0BzvLiIKEGp8SUUq9XGIEoYZ9l6BueW0xQVUg,2849
|
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=xLejXelEae695DTN9T6fLbCu1YgIQIH-tFYQotJuCPI,11319
|
17
|
-
fotolab-0.32.0.dist-info/licenses/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
18
|
-
fotolab-0.32.0.dist-info/METADATA,sha256=PDhVkW_L-sLLojnhkbwRkpmT_hGq7C3ibinBUFXIEq8,14765
|
19
|
-
fotolab-0.32.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
20
|
-
fotolab-0.32.0.dist-info/entry_points.txt,sha256=0e1go9plFpqj5FP-OpV2acxTAx3ViI59PMXuhejvgcQ,45
|
21
|
-
fotolab-0.32.0.dist-info/top_level.txt,sha256=XUJ3gdpsbjohoZCLdVlbQrxAUDkbQg7WwGQG2DaN0t4,8
|
22
|
-
fotolab-0.32.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|