fotolab 0.10.0__py2.py3-none-any.whl → 0.12.0__py2.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 +5 -2
- fotolab/auto.py +1 -0
- fotolab/cli.py +3 -1
- fotolab/montage.py +70 -0
- fotolab/watermark.py +19 -5
- {fotolab-0.10.0.dist-info → fotolab-0.12.0.dist-info}/METADATA +44 -4
- fotolab-0.12.0.dist-info/RECORD +17 -0
- fotolab-0.10.0.dist-info/RECORD +0 -16
- {fotolab-0.10.0.dist-info → fotolab-0.12.0.dist-info}/LICENSE.md +0 -0
- {fotolab-0.10.0.dist-info → fotolab-0.12.0.dist-info}/WHEEL +0 -0
- {fotolab-0.10.0.dist-info → fotolab-0.12.0.dist-info}/entry_points.txt +0 -0
fotolab/__init__.py
CHANGED
@@ -21,7 +21,7 @@ import subprocess
|
|
21
21
|
import sys
|
22
22
|
from pathlib import Path
|
23
23
|
|
24
|
-
__version__ = "0.
|
24
|
+
__version__ = "0.12.0"
|
25
25
|
|
26
26
|
log = logging.getLogger(__name__)
|
27
27
|
|
@@ -37,7 +37,10 @@ def save_image(args, new_image, subcommand):
|
|
37
37
|
Returns:
|
38
38
|
None
|
39
39
|
"""
|
40
|
-
|
40
|
+
if "image_filenames" in args:
|
41
|
+
image_file = Path(args.image_filenames[0].name)
|
42
|
+
else:
|
43
|
+
image_file = Path(args.image_filename)
|
41
44
|
|
42
45
|
if args.overwrite:
|
43
46
|
new_filename = image_file.with_name(image_file.name)
|
fotolab/auto.py
CHANGED
fotolab/cli.py
CHANGED
@@ -30,6 +30,7 @@ import fotolab.border
|
|
30
30
|
import fotolab.contrast
|
31
31
|
import fotolab.env
|
32
32
|
import fotolab.info
|
33
|
+
import fotolab.montage
|
33
34
|
import fotolab.resize
|
34
35
|
import fotolab.sharpen
|
35
36
|
import fotolab.watermark
|
@@ -83,7 +84,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
83
84
|
default=False,
|
84
85
|
action="store_true",
|
85
86
|
dest="open",
|
86
|
-
help="open the image using default program (default: '%(default)s'",
|
87
|
+
help="open the image using default program (default: '%(default)s')",
|
87
88
|
)
|
88
89
|
|
89
90
|
parser.add_argument(
|
@@ -125,6 +126,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
125
126
|
fotolab.contrast.build_subparser(subparsers)
|
126
127
|
fotolab.info.build_subparser(subparsers)
|
127
128
|
fotolab.resize.build_subparser(subparsers)
|
129
|
+
fotolab.montage.build_subparser(subparsers)
|
128
130
|
fotolab.sharpen.build_subparser(subparsers)
|
129
131
|
fotolab.watermark.build_subparser(subparsers)
|
130
132
|
fotolab.env.build_subparser(subparsers)
|
fotolab/montage.py
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Copyright (C) 2024 Kian-Meng Ang
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify it under
|
4
|
+
# the terms of the GNU Affero General Public License as published by the Free
|
5
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
6
|
+
# later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
9
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
10
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
11
|
+
# details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
"""Montage subcommand."""
|
17
|
+
|
18
|
+
import argparse
|
19
|
+
import logging
|
20
|
+
|
21
|
+
from PIL import Image
|
22
|
+
|
23
|
+
from fotolab import save_image
|
24
|
+
|
25
|
+
log = logging.getLogger(__name__)
|
26
|
+
|
27
|
+
|
28
|
+
def build_subparser(subparsers) -> None:
|
29
|
+
"""Build the subparser."""
|
30
|
+
montage_parser = subparsers.add_parser(
|
31
|
+
"montage", help="montage a list of image"
|
32
|
+
)
|
33
|
+
|
34
|
+
montage_parser.set_defaults(func=run)
|
35
|
+
|
36
|
+
montage_parser.add_argument(
|
37
|
+
dest="image_filenames",
|
38
|
+
help="set the image filenames",
|
39
|
+
nargs="+",
|
40
|
+
type=argparse.FileType("r"),
|
41
|
+
default=None,
|
42
|
+
metavar="IMAGE_FILENAMES",
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
def run(args: argparse.Namespace) -> None:
|
47
|
+
"""Run montage subcommand.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
config (argparse.Namespace): Config from command line arguments
|
51
|
+
|
52
|
+
Returns:
|
53
|
+
None
|
54
|
+
"""
|
55
|
+
log.debug(args)
|
56
|
+
images = []
|
57
|
+
for image_filename in args.image_filenames:
|
58
|
+
images.append(Image.open(image_filename.name))
|
59
|
+
|
60
|
+
total_width = sum(img.width for img in images)
|
61
|
+
total_height = max(img.height for img in images)
|
62
|
+
|
63
|
+
montaged_image = Image.new("RGB", (total_width, total_height))
|
64
|
+
|
65
|
+
x_offset = 0
|
66
|
+
for img in images:
|
67
|
+
montaged_image.paste(img, (x_offset, 0))
|
68
|
+
x_offset += img.width
|
69
|
+
|
70
|
+
save_image(args, montaged_image, "montage")
|
fotolab/watermark.py
CHANGED
@@ -62,6 +62,19 @@ def build_subparser(subparsers) -> None:
|
|
62
62
|
default="bottom-left",
|
63
63
|
)
|
64
64
|
|
65
|
+
watermark_parser.add_argument(
|
66
|
+
"-pd",
|
67
|
+
"--padding",
|
68
|
+
dest="padding",
|
69
|
+
type=int,
|
70
|
+
default=15,
|
71
|
+
help=(
|
72
|
+
"set the padding of the watermark text relative to the image "
|
73
|
+
"(default: '%(default)s')"
|
74
|
+
),
|
75
|
+
metavar="PADDING",
|
76
|
+
)
|
77
|
+
|
65
78
|
watermark_parser.add_argument(
|
66
79
|
"-fs",
|
67
80
|
"--font-size",
|
@@ -133,24 +146,25 @@ def run(args: argparse.Namespace) -> None:
|
|
133
146
|
text_width = right - left
|
134
147
|
text_height = bottom - top
|
135
148
|
(position_x, position_y) = calculate_position(
|
136
|
-
watermarked_image, text_width, text_height, args.position
|
149
|
+
watermarked_image, text_width, text_height, args.position, args.padding
|
137
150
|
)
|
138
151
|
|
139
152
|
draw.text(
|
140
153
|
(position_x, position_y),
|
141
154
|
args.text,
|
142
155
|
font=font,
|
143
|
-
fill=ImageColor.getrgb(args.font_color),
|
156
|
+
fill=(*ImageColor.getrgb(args.font_color), 128),
|
144
157
|
stroke_width=args.outline_width,
|
145
|
-
stroke_fill=ImageColor.getrgb(args.outline_color),
|
158
|
+
stroke_fill=(*ImageColor.getrgb(args.outline_color), 128),
|
146
159
|
)
|
147
160
|
|
148
161
|
save_image(args, watermarked_image, "watermark")
|
149
162
|
|
150
163
|
|
151
|
-
def calculate_position(
|
164
|
+
def calculate_position(
|
165
|
+
image, text_width, text_height, position, padding
|
166
|
+
) -> tuple:
|
152
167
|
"""Calculate the boundary coordinates of the watermark text."""
|
153
|
-
padding = 10
|
154
168
|
if position == "top-left":
|
155
169
|
position_x = 0 + padding
|
156
170
|
position_y = 0 + padding
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: fotolab
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.12.0
|
4
4
|
Summary: A console program that manipulate images.
|
5
5
|
Keywords: photography,photo
|
6
6
|
Author-email: Kian-Meng Ang <kianmeng@cpan.org>
|
@@ -89,6 +89,22 @@ optional arguments:
|
|
89
89
|
-V, --version show program's version number and exit
|
90
90
|
```
|
91
91
|
|
92
|
+
### fotolab auto
|
93
|
+
|
94
|
+
```console
|
95
|
+
fotolab auto -h
|
96
|
+
```
|
97
|
+
|
98
|
+
```console
|
99
|
+
usage: fotolab auto [-h] IMAGE_FILENAME
|
100
|
+
|
101
|
+
positional arguments:
|
102
|
+
IMAGE_FILENAME set the image filename
|
103
|
+
|
104
|
+
optional arguments:
|
105
|
+
-h, --help show this help message and exit
|
106
|
+
```
|
107
|
+
|
92
108
|
### fotolab border
|
93
109
|
|
94
110
|
```console
|
@@ -151,6 +167,27 @@ optional arguments:
|
|
151
167
|
-h, --help show this help message and exit
|
152
168
|
```
|
153
169
|
|
170
|
+
### fotolab resize
|
171
|
+
|
172
|
+
```console
|
173
|
+
fotolab resize -h
|
174
|
+
```
|
175
|
+
|
176
|
+
```console
|
177
|
+
|
178
|
+
usage: fotolab resize [-h] [-wh WIDTH] [-ht HEIGHT] IMAGE_FILENAME
|
179
|
+
|
180
|
+
positional arguments:
|
181
|
+
IMAGE_FILENAME set the image filename
|
182
|
+
|
183
|
+
optional arguments:
|
184
|
+
-h, --help show this help message and exit
|
185
|
+
-wh WIDTH, --width WIDTH
|
186
|
+
set the width of the image (default: '600')
|
187
|
+
-ht HEIGHT, --height HEIGHT
|
188
|
+
set the height of the image (default: '277')
|
189
|
+
```
|
190
|
+
|
154
191
|
### fotolab sharpen
|
155
192
|
|
156
193
|
```console
|
@@ -176,20 +213,23 @@ fotolab watermark -h
|
|
176
213
|
```console
|
177
214
|
usage: fotolab watermark [-h] [-t WATERMARK_TEXT]
|
178
215
|
[-p {top-left,top-right,bottom-left,bottom-right}]
|
179
|
-
[-
|
180
|
-
[-oc OUTLINE_COLOR]
|
216
|
+
[-pd PADDING] [-fs FONT_SIZE] [-fc FONT_COLOR]
|
217
|
+
[-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR]
|
181
218
|
IMAGE_FILENAME
|
182
219
|
|
183
220
|
positional arguments:
|
184
221
|
IMAGE_FILENAME set the image filename
|
185
222
|
|
186
|
-
|
223
|
+
optional arguments:
|
187
224
|
-h, --help show this help message and exit
|
188
225
|
-t WATERMARK_TEXT, --text WATERMARK_TEXT
|
189
226
|
set the watermark text (default: 'kianmeng.org')
|
190
227
|
-p {top-left,top-right,bottom-left,bottom-right}, --position {top-left,top-right,bottom-left,bottom-right}
|
191
228
|
set position of the watermark text (default: 'bottom-
|
192
229
|
left')
|
230
|
+
-pd PADDING, --padding PADDING
|
231
|
+
set the padding of the watermark text relative to the
|
232
|
+
image (default: '15')
|
193
233
|
-fs FONT_SIZE, --font-size FONT_SIZE
|
194
234
|
set the font size of watermark text (default: '12')
|
195
235
|
-fc FONT_COLOR, --font-color FONT_COLOR
|
@@ -0,0 +1,17 @@
|
|
1
|
+
fotolab/__init__.py,sha256=8ti89bThRtE551s8nHCPDhKpKl_n62Bh4QZW1JyvJGk,2165
|
2
|
+
fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
|
3
|
+
fotolab/auto.py,sha256=QvRBRhbhU9ZKEFDYiPkfENgYVOTP6Gt39zYGJd_BIDI,2196
|
4
|
+
fotolab/border.py,sha256=vujylADWHQsFwoCjoUa2yOIi8aJhTrVBgZsqyxDHKV0,3423
|
5
|
+
fotolab/cli.py,sha256=KoSDb752mewrtKE5wDs9icXF2McBVOKoEB98KYAV-jQ,4570
|
6
|
+
fotolab/contrast.py,sha256=82dpsFHW6kW7tR0kekFn1UoZAuAq3EXWQNOmrtRGw2g,1981
|
7
|
+
fotolab/env.py,sha256=NTTvfISWBBfIw5opWrUfg0BtkaAtdUtcISBAJC2gVUk,1449
|
8
|
+
fotolab/info.py,sha256=DawXTQJiQDBwy0Ml5Ysk8MvKga3ikp_aIw73AR3LdZo,1687
|
9
|
+
fotolab/montage.py,sha256=wQApMwQsOett6TwxCT8JhqM5X2DoS2tjEyTxsomiwM4,1957
|
10
|
+
fotolab/resize.py,sha256=EkZYyWw9jHVmexIVbF3a9v5MYQEQxjVXlGGBMoB0IeQ,2138
|
11
|
+
fotolab/sharpen.py,sha256=DGeIq24JHpfftAF_h26cTMJVwSsxmnB9bL7lPkynuco,2546
|
12
|
+
fotolab/watermark.py,sha256=syNzsr4xIjQDPyDLwezzmy2Emi3AzZBKXwM422ZIVQc,4996
|
13
|
+
fotolab-0.12.0.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
|
14
|
+
fotolab-0.12.0.dist-info/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
15
|
+
fotolab-0.12.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
|
16
|
+
fotolab-0.12.0.dist-info/METADATA,sha256=COUB8nxicWSmFFEIhAdDHmdAz--GN0Gb0lyShqPP1J8,7875
|
17
|
+
fotolab-0.12.0.dist-info/RECORD,,
|
fotolab-0.10.0.dist-info/RECORD
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
fotolab/__init__.py,sha256=rLzpwtU7DbbHRYPQ4hQCyhQdg6OrvKeftKLf0PaytXo,2061
|
2
|
-
fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
|
3
|
-
fotolab/auto.py,sha256=k4DkHQp05m7UYUgHRrH9L1d0eSgOzrn2Cyk5BG27KyA,2173
|
4
|
-
fotolab/border.py,sha256=vujylADWHQsFwoCjoUa2yOIi8aJhTrVBgZsqyxDHKV0,3423
|
5
|
-
fotolab/cli.py,sha256=erXr3MXmMXQ9bDu9T6ZoOoRW0Yzt2z8anlSPJHkHtBk,4498
|
6
|
-
fotolab/contrast.py,sha256=82dpsFHW6kW7tR0kekFn1UoZAuAq3EXWQNOmrtRGw2g,1981
|
7
|
-
fotolab/env.py,sha256=NTTvfISWBBfIw5opWrUfg0BtkaAtdUtcISBAJC2gVUk,1449
|
8
|
-
fotolab/info.py,sha256=DawXTQJiQDBwy0Ml5Ysk8MvKga3ikp_aIw73AR3LdZo,1687
|
9
|
-
fotolab/resize.py,sha256=EkZYyWw9jHVmexIVbF3a9v5MYQEQxjVXlGGBMoB0IeQ,2138
|
10
|
-
fotolab/sharpen.py,sha256=DGeIq24JHpfftAF_h26cTMJVwSsxmnB9bL7lPkynuco,2546
|
11
|
-
fotolab/watermark.py,sha256=8qHkGzjw726pv8z8wY5dH70-7lnr9Zr-VXkZep3VSac,4661
|
12
|
-
fotolab-0.10.0.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
|
13
|
-
fotolab-0.10.0.dist-info/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
|
14
|
-
fotolab-0.10.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
|
15
|
-
fotolab-0.10.0.dist-info/METADATA,sha256=SunRTn8v-nCy8Pw5N9qGLewPSyxyo9-t7On3RxCwHPI,6973
|
16
|
-
fotolab-0.10.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|