fotolab 0.9.0__py2.py3-none-any.whl → 0.13.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 CHANGED
@@ -19,12 +19,42 @@ import logging
19
19
  import os
20
20
  import subprocess
21
21
  import sys
22
+ from pathlib import Path
22
23
 
23
- __version__ = "0.9.0"
24
+ __version__ = "0.13.0"
24
25
 
25
26
  log = logging.getLogger(__name__)
26
27
 
27
28
 
29
+ def save_image(args, new_image, output_filename, subcommand):
30
+ """Save image after image operation.
31
+
32
+ Args:
33
+ args (argparse.Namespace): Config from command line arguments
34
+ new_image(PIL.Image.Image): Modified image
35
+ subcommand(str): Subcommand used to call this function
36
+
37
+ Returns:
38
+ None
39
+ """
40
+ image_file = Path(output_filename)
41
+
42
+ if args.overwrite:
43
+ new_filename = image_file.with_name(image_file.name)
44
+ else:
45
+ new_filename = Path(
46
+ args.output_dir,
47
+ image_file.with_name(f"{subcommand}_{image_file.name}"),
48
+ )
49
+ new_filename.parent.mkdir(parents=True, exist_ok=True)
50
+
51
+ log.info("%s image: %s", subcommand, new_filename)
52
+ new_image.save(new_filename)
53
+
54
+ if args.open:
55
+ _open_image(new_filename)
56
+
57
+
28
58
  def _open_image(filename):
29
59
  """Open generated image using default program."""
30
60
  if sys.platform == "linux":
fotolab/auto.py CHANGED
@@ -35,11 +35,12 @@ def build_subparser(subparsers) -> None:
35
35
  auto_parser.set_defaults(func=run)
36
36
 
37
37
  auto_parser.add_argument(
38
- dest="image_filename",
38
+ dest="image_filenames",
39
39
  help="set the image filename",
40
+ nargs="+",
40
41
  type=str,
41
42
  default=None,
42
- metavar="IMAGE_FILENAME",
43
+ metavar="IMAGE_FILENAMES",
43
44
  )
44
45
 
45
46
 
@@ -65,9 +66,11 @@ def run(args: argparse.Namespace) -> None:
65
66
  "font_color": "white",
66
67
  "outline_width": 2,
67
68
  "outline_color": "black",
69
+ "padding": 15,
68
70
  }
69
71
  combined_args = argparse.Namespace(**vars(args), **extra_args)
70
72
  combined_args.overwrite = True
73
+ combined_args.open = False
71
74
  log.debug(args)
72
75
  log.debug(combined_args)
73
76
 
fotolab/border.py CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  import argparse
19
19
  import logging
20
- from pathlib import Path
21
20
 
22
21
  from PIL import Image, ImageColor, ImageOps
23
22
 
23
+ from fotolab import save_image
24
+
24
25
  log = logging.getLogger(__name__)
25
26
 
26
27
 
@@ -31,11 +32,12 @@ def build_subparser(subparsers) -> None:
31
32
  border_parser.set_defaults(func=run)
32
33
 
33
34
  border_parser.add_argument(
34
- dest="image_filename",
35
- help="set the image filename",
35
+ dest="image_filenames",
36
+ help="set the image filenames",
37
+ nargs="+",
36
38
  type=str,
37
39
  default=None,
38
- metavar="IMAGE_FILENAME",
40
+ metavar="IMAGE_FILENAMES",
39
41
  )
40
42
 
41
43
  border_parser.add_argument(
@@ -110,38 +112,28 @@ def run(args: argparse.Namespace) -> None:
110
112
  """
111
113
  log.debug(args)
112
114
 
113
- image_file = Path(args.image_filename)
114
-
115
- original_image = Image.open(args.image_filename)
116
-
117
- if (
118
- args.width_left
119
- or args.width_top
120
- or args.width_right
121
- or args.width_bottom
122
- ):
123
- border = (
124
- int(args.width_left),
125
- int(args.width_top),
126
- int(args.width_right),
127
- int(args.width_bottom),
128
- )
129
- else:
130
- border = args.width
131
-
132
- bordered_image = ImageOps.expand(
133
- original_image,
134
- border=border,
135
- fill=ImageColor.getrgb(args.color),
136
- )
137
-
138
- if args.overwrite:
139
- new_filename = image_file.with_name(image_file.name)
140
- else:
141
- new_filename = Path(
142
- args.output_dir, image_file.with_name(f"border_{image_file.name}")
115
+ for image_filename in args.image_filenames:
116
+ original_image = Image.open(image_filename)
117
+
118
+ if (
119
+ args.width_left
120
+ or args.width_top
121
+ or args.width_right
122
+ or args.width_bottom
123
+ ):
124
+ border = (
125
+ int(args.width_left),
126
+ int(args.width_top),
127
+ int(args.width_right),
128
+ int(args.width_bottom),
129
+ )
130
+ else:
131
+ border = args.width
132
+
133
+ bordered_image = ImageOps.expand(
134
+ original_image,
135
+ border=border,
136
+ fill=ImageColor.getrgb(args.color),
143
137
  )
144
- new_filename.parent.mkdir(parents=True, exist_ok=True)
145
138
 
146
- log.info("creating image: %s", new_filename)
147
- bordered_image.save(new_filename)
139
+ save_image(args, bordered_image, image_filename, "watermark")
fotolab/cli.py CHANGED
@@ -29,6 +29,8 @@ import fotolab.auto
29
29
  import fotolab.border
30
30
  import fotolab.contrast
31
31
  import fotolab.env
32
+ import fotolab.info
33
+ import fotolab.montage
32
34
  import fotolab.resize
33
35
  import fotolab.sharpen
34
36
  import fotolab.watermark
@@ -82,7 +84,7 @@ def build_parser() -> argparse.ArgumentParser:
82
84
  default=False,
83
85
  action="store_true",
84
86
  dest="open",
85
- help="open the image using default program (default: '%(default)s'",
87
+ help="open the image using default program (default: '%(default)s')",
86
88
  )
87
89
 
88
90
  parser.add_argument(
@@ -122,7 +124,9 @@ def build_parser() -> argparse.ArgumentParser:
122
124
  fotolab.auto.build_subparser(subparsers)
123
125
  fotolab.border.build_subparser(subparsers)
124
126
  fotolab.contrast.build_subparser(subparsers)
127
+ fotolab.info.build_subparser(subparsers)
125
128
  fotolab.resize.build_subparser(subparsers)
129
+ fotolab.montage.build_subparser(subparsers)
126
130
  fotolab.sharpen.build_subparser(subparsers)
127
131
  fotolab.watermark.build_subparser(subparsers)
128
132
  fotolab.env.build_subparser(subparsers)
fotolab/contrast.py CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  import argparse
19
19
  import logging
20
- from pathlib import Path
21
20
 
22
21
  from PIL import Image, ImageOps
23
22
 
23
+ from fotolab import save_image
24
+
24
25
  log = logging.getLogger(__name__)
25
26
 
26
27
 
@@ -33,11 +34,12 @@ def build_subparser(subparsers) -> None:
33
34
  contrast_parser.set_defaults(func=run)
34
35
 
35
36
  contrast_parser.add_argument(
36
- dest="image_filename",
37
+ dest="image_filenames",
37
38
  help="set the image filename",
39
+ nargs="+",
38
40
  type=str,
39
41
  default=None,
40
- metavar="IMAGE_FILENAME",
42
+ metavar="IMAGE_FILENAMES",
41
43
  )
42
44
 
43
45
  contrast_parser.add_argument(
@@ -66,19 +68,10 @@ def run(args: argparse.Namespace) -> None:
66
68
  """
67
69
  log.debug(args)
68
70
 
69
- image_file = Path(args.image_filename)
70
-
71
- original_image = Image.open(args.image_filename)
72
- contrast_image = ImageOps.autocontrast(original_image, cutoff=args.cutoff)
73
-
74
- if args.overwrite:
75
- new_filename = image_file.with_name(image_file.name)
76
- else:
77
- new_filename = Path(
78
- args.output_dir,
79
- image_file.with_name(f"contrast_{image_file.name}"),
71
+ for image_filename in args.image_filenames:
72
+ original_image = Image.open(image_filename)
73
+ contrast_image = ImageOps.autocontrast(
74
+ original_image, cutoff=args.cutoff
80
75
  )
81
- new_filename.parent.mkdir(parents=True, exist_ok=True)
82
76
 
83
- log.info("contrasting image: %s", new_filename)
84
- contrast_image.save(new_filename)
77
+ save_image(args, contrast_image, image_filename, "contrast")
fotolab/env.py CHANGED
@@ -45,6 +45,8 @@ def run(args: argparse.Namespace) -> None:
45
45
  """
46
46
  log.debug(args)
47
47
 
48
+ sys_version = sys.version.replace("\n", "")
49
+
48
50
  print(f"fotolab: {__version__}")
49
- print(f"python: {sys.version}")
51
+ print(f"python: {sys_version}")
50
52
  print(f"platform: {platform.platform()}")
fotolab/info.py ADDED
@@ -0,0 +1,58 @@
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
+ """Info subcommand."""
17
+
18
+ import argparse
19
+ import logging
20
+
21
+ from PIL import ExifTags, Image
22
+
23
+ log = logging.getLogger(__name__)
24
+
25
+
26
+ def build_subparser(subparsers) -> None:
27
+ """Build the subparser."""
28
+ info_parser = subparsers.add_parser("info", help="info an image")
29
+
30
+ info_parser.set_defaults(func=run)
31
+
32
+ info_parser.add_argument(
33
+ dest="image_filename",
34
+ help="set the image filename",
35
+ type=str,
36
+ default=None,
37
+ metavar="IMAGE_FILENAME",
38
+ )
39
+
40
+
41
+ def run(args: argparse.Namespace) -> None:
42
+ """Run info subcommand.
43
+
44
+ Args:
45
+ config (argparse.Namespace): Config from command line arguments
46
+
47
+ Returns:
48
+ None
49
+ """
50
+ log.debug(args)
51
+
52
+ image = Image.open(args.image_filename)
53
+ exif = image._getexif()
54
+ info = {ExifTags.TAGS.get(tag_id): exif.get(tag_id) for tag_id in exif}
55
+
56
+ tag_name_width = max(map(len, info))
57
+ for tag_name, tag_value in info.items():
58
+ print(f"{tag_name:<{tag_name_width}}: {tag_value}")
fotolab/montage.py ADDED
@@ -0,0 +1,71 @@
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
+ output_image_filename = args.image_filenames[0].name
71
+ save_image(args, montaged_image, output_image_filename, "montage")
fotolab/resize.py CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  import argparse
19
19
  import logging
20
- from pathlib import Path
21
20
 
22
21
  from PIL import Image
23
22
 
23
+ from fotolab import save_image
24
+
24
25
  log = logging.getLogger(__name__)
25
26
 
26
27
 
@@ -31,11 +32,12 @@ def build_subparser(subparsers) -> None:
31
32
  resize_parser.set_defaults(func=run)
32
33
 
33
34
  resize_parser.add_argument(
34
- dest="image_filename",
35
+ dest="image_filenames",
35
36
  help="set the image filename",
37
+ nargs="+",
36
38
  type=str,
37
39
  default=None,
38
- metavar="IMAGE_FILENAME",
40
+ metavar="IMAGE_FILENAMES",
39
41
  )
40
42
 
41
43
  resize_parser.add_argument(
@@ -63,28 +65,18 @@ def run(args: argparse.Namespace) -> None:
63
65
  """Run resize subcommand.
64
66
 
65
67
  Args:
66
- config (argparse.Namespace): Config from command line arguments
68
+ args (argparse.Namespace): Config from command line arguments
67
69
 
68
70
  Returns:
69
71
  None
70
72
  """
71
73
  log.debug(args)
72
74
 
73
- image_file = Path(args.image_filename)
74
- original_image = Image.open(args.image_filename)
75
- resized_image = original_image.copy()
76
- resized_image = resized_image.resize(
77
- (args.width, args.height), Image.Resampling.LANCZOS
78
- )
79
-
80
- if args.overwrite:
81
- new_filename = image_file.with_name(image_file.name)
82
- else:
83
- new_filename = Path(
84
- args.output_dir,
85
- image_file.with_name(f"resize_{image_file.name}"),
75
+ for image_filename in args.image_filenames:
76
+ original_image = Image.open(image_filename)
77
+ resized_image = original_image.copy()
78
+ resized_image = resized_image.resize(
79
+ (args.width, args.height), Image.Resampling.LANCZOS
86
80
  )
87
- new_filename.parent.mkdir(parents=True, exist_ok=True)
88
81
 
89
- log.info("resizing image: %s", new_filename)
90
- resized_image.save(new_filename)
82
+ save_image(args, resized_image, image_filename, "resize")
fotolab/sharpen.py CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  import argparse
19
19
  import logging
20
- from pathlib import Path
21
20
 
22
21
  from PIL import Image, ImageFilter
23
22
 
23
+ from fotolab import save_image
24
+
24
25
  log = logging.getLogger(__name__)
25
26
 
26
27
 
@@ -31,11 +32,12 @@ def build_subparser(subparsers) -> None:
31
32
  sharpen_parser.set_defaults(func=run)
32
33
 
33
34
  sharpen_parser.add_argument(
34
- dest="image_filename",
35
- help="set the image filename",
35
+ dest="image_filenames",
36
+ help="set the image filenames",
37
+ nargs="+",
36
38
  type=str,
37
39
  default=None,
38
- metavar="IMAGE_FILENAME",
40
+ metavar="IMAGE_FILENAMES",
39
41
  )
40
42
 
41
43
  sharpen_parser.add_argument(
@@ -86,22 +88,11 @@ def run(args: argparse.Namespace) -> None:
86
88
  """
87
89
  log.debug(args)
88
90
 
89
- image_file = Path(args.image_filename)
90
-
91
- original_image = Image.open(args.image_filename)
92
- sharpen_image = original_image.filter(
93
- ImageFilter.UnsharpMask(
94
- args.radius, percent=args.percent, threshold=args.threshold
95
- )
96
- )
97
-
98
- if args.overwrite:
99
- new_filename = image_file.with_name(image_file.name)
100
- else:
101
- new_filename = Path(
102
- args.output_dir, image_file.with_name(f"sharpen_{image_file.name}")
91
+ for image_filename in args.image_filenames:
92
+ original_image = Image.open(image_filename)
93
+ sharpen_image = original_image.filter(
94
+ ImageFilter.UnsharpMask(
95
+ args.radius, percent=args.percent, threshold=args.threshold
96
+ )
103
97
  )
104
- new_filename.parent.mkdir(parents=True, exist_ok=True)
105
-
106
- log.info("sharpening image: %s", new_filename)
107
- sharpen_image.save(new_filename)
98
+ save_image(args, sharpen_image, image_filename, "sharpen")
fotolab/watermark.py CHANGED
@@ -17,10 +17,11 @@
17
17
 
18
18
  import argparse
19
19
  import logging
20
- from pathlib import Path
21
20
 
22
21
  from PIL import Image, ImageColor, ImageDraw, ImageFont
23
22
 
23
+ from fotolab import save_image
24
+
24
25
  log = logging.getLogger(__name__)
25
26
 
26
27
  POSITIONS = ["top-left", "top-right", "bottom-left", "bottom-right"]
@@ -35,11 +36,12 @@ def build_subparser(subparsers) -> None:
35
36
  watermark_parser.set_defaults(func=run)
36
37
 
37
38
  watermark_parser.add_argument(
38
- dest="image_filename",
39
- help="set the image filename",
39
+ dest="image_filenames",
40
+ help="set the image filenames",
41
+ nargs="+",
40
42
  type=str,
41
43
  default=None,
42
- metavar="IMAGE_FILENAME",
44
+ metavar="IMAGE_FILENAMES",
43
45
  )
44
46
 
45
47
  watermark_parser.add_argument(
@@ -61,6 +63,19 @@ def build_subparser(subparsers) -> None:
61
63
  default="bottom-left",
62
64
  )
63
65
 
66
+ watermark_parser.add_argument(
67
+ "-pd",
68
+ "--padding",
69
+ dest="padding",
70
+ type=int,
71
+ default=15,
72
+ help=(
73
+ "set the padding of the watermark text relative to the image "
74
+ "(default: '%(default)s')"
75
+ ),
76
+ metavar="PADDING",
77
+ )
78
+
64
79
  watermark_parser.add_argument(
65
80
  "-fs",
66
81
  "--font-size",
@@ -119,49 +134,43 @@ def run(args: argparse.Namespace) -> None:
119
134
  """
120
135
  log.debug(args)
121
136
 
122
- image_file = Path(args.image_filename)
137
+ for image_filename in args.image_filenames:
138
+ original_image = Image.open(image_filename)
139
+ watermarked_image = original_image.copy()
123
140
 
124
- original_image = Image.open(args.image_filename)
125
- watermarked_image = original_image.copy()
141
+ draw = ImageDraw.Draw(watermarked_image)
126
142
 
127
- draw = ImageDraw.Draw(watermarked_image)
143
+ font = ImageFont.truetype("arial.ttf", args.font_size)
128
144
 
129
- font = ImageFont.truetype("arial.ttf", args.font_size)
130
-
131
- (left, top, right, bottom) = draw.textbbox(
132
- xy=(0, 0), text=args.text, font=font
133
- )
134
- text_width = right - left
135
- text_height = bottom - top
136
- (position_x, position_y) = calculate_position(
137
- watermarked_image, text_width, text_height, args.position
138
- )
139
-
140
- draw.text(
141
- (position_x, position_y),
142
- args.text,
143
- font=font,
144
- fill=ImageColor.getrgb(args.font_color),
145
- stroke_width=args.outline_width,
146
- stroke_fill=ImageColor.getrgb(args.outline_color),
147
- )
145
+ (left, top, right, bottom) = draw.textbbox(
146
+ xy=(0, 0), text=args.text, font=font
147
+ )
148
+ text_width = right - left
149
+ text_height = bottom - top
150
+ (position_x, position_y) = calculate_position(
151
+ watermarked_image,
152
+ text_width,
153
+ text_height,
154
+ args.position,
155
+ args.padding,
156
+ )
148
157
 
149
- if args.overwrite:
150
- new_filename = image_file.with_name(image_file.name)
151
- else:
152
- new_filename = Path(
153
- args.output_dir,
154
- image_file.with_name(f"watermark_{image_file.name}"),
158
+ draw.text(
159
+ (position_x, position_y),
160
+ args.text,
161
+ font=font,
162
+ fill=(*ImageColor.getrgb(args.font_color), 128),
163
+ stroke_width=args.outline_width,
164
+ stroke_fill=(*ImageColor.getrgb(args.outline_color), 128),
155
165
  )
156
- new_filename.parent.mkdir(parents=True, exist_ok=True)
157
166
 
158
- log.info("watermarking image: %s", new_filename)
159
- watermarked_image.save(new_filename)
167
+ save_image(args, watermarked_image, image_filename, "watermark")
160
168
 
161
169
 
162
- def calculate_position(image, text_width, text_height, position) -> tuple:
170
+ def calculate_position(
171
+ image, text_width, text_height, position, padding
172
+ ) -> tuple:
163
173
  """Calculate the boundary coordinates of the watermark text."""
164
- padding = 10
165
174
  if position == "top-left":
166
175
  position_x = 0 + padding
167
176
  position_y = 0 + padding
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fotolab
3
- Version: 0.9.0
3
+ Version: 0.13.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>
@@ -57,9 +57,9 @@ fotolab -h
57
57
  ```
58
58
 
59
59
  ```console
60
-
61
60
  usage: fotolab [-h] [-o] [-op] [-od OUTPUT_DIR] [-q] [-d] [-V]
62
- {auto,border,contrast,resize,sharpen,watermark,env} ...
61
+ {auto,border,contrast,info,resize,montage,sharpen,watermark,env}
62
+ ...
63
63
 
64
64
  A console program to manipulate photos.
65
65
 
@@ -68,12 +68,14 @@ A console program to manipulate photos.
68
68
  issues: https://github.com/kianmeng/fotolab/issues
69
69
 
70
70
  positional arguments:
71
- {auto,border,contrast,resize,sharpen,watermark,env}
71
+ {auto,border,contrast,info,resize,montage,sharpen,watermark,env}
72
72
  sub-command help
73
73
  auto auto adjust (resize, contrast, and watermark) a photo
74
74
  border add border to image
75
75
  contrast contrast an image
76
+ info info an image
76
77
  resize resize an image
78
+ montage montage a list of image
77
79
  sharpen sharpen an image
78
80
  watermark watermark an image
79
81
  env print environment information for bug reporting
@@ -81,7 +83,7 @@ positional arguments:
81
83
  optional arguments:
82
84
  -h, --help show this help message and exit
83
85
  -o, --overwrite overwrite existing image
84
- -op, --open open the image using default program (default: 'False'
86
+ -op, --open open the image using default program (default: 'False')
85
87
  -od OUTPUT_DIR, --output-dir OUTPUT_DIR
86
88
  set default output folder (default: 'output')
87
89
  -q, --quiet suppress all logging
@@ -89,6 +91,22 @@ optional arguments:
89
91
  -V, --version show program's version number and exit
90
92
  ```
91
93
 
94
+ ### fotolab auto
95
+
96
+ ```console
97
+ fotolab auto -h
98
+ ```
99
+
100
+ ```console
101
+ usage: fotolab auto [-h] IMAGE_FILENAMES [IMAGE_FILENAMES ...]
102
+
103
+ positional arguments:
104
+ IMAGE_FILENAMES set the image filename
105
+
106
+ optional arguments:
107
+ -h, --help show this help message and exit
108
+ ```
109
+
92
110
  ### fotolab border
93
111
 
94
112
  ```console
@@ -98,12 +116,12 @@ fotolab border -h
98
116
  ```console
99
117
  usage: fotolab border [-h] [-c COLOR] [-w WIDTH] [-wt WIDTH] [-wr WIDTH]
100
118
  [-wb WIDTH] [-wl WIDTH]
101
- IMAGE_FILENAME
119
+ IMAGE_FILENAMES [IMAGE_FILENAMES ...]
102
120
 
103
121
  positional arguments:
104
- IMAGE_FILENAME set the image filename
122
+ IMAGE_FILENAMES set the image filenames
105
123
 
106
- options:
124
+ optional arguments:
107
125
  -h, --help show this help message and exit
108
126
  -c COLOR, --color COLOR
109
127
  set the color of border (default: 'black')
@@ -126,7 +144,26 @@ fotolab contrast -h
126
144
  ```
127
145
 
128
146
  ```console
129
- usage: fotolab contrast [-h] IMAGE_FILENAME
147
+ usage: fotolab contrast [-h] [-c CUTOFF] IMAGE_FILENAMES [IMAGE_FILENAMES ...]
148
+
149
+ positional arguments:
150
+ IMAGE_FILENAMES set the image filename
151
+
152
+ optional arguments:
153
+ -h, --help show this help message and exit
154
+ -c CUTOFF, --cutoff CUTOFF
155
+ set the percentage of lightest or darkest pixels to
156
+ discard from histogram (default: '1')
157
+ ```
158
+
159
+ ### fotolab info
160
+
161
+ ```console
162
+ fotolab info -h
163
+ ```
164
+
165
+ ```console
166
+ usage: fotolab info [-h] IMAGE_FILENAME
130
167
 
131
168
  positional arguments:
132
169
  IMAGE_FILENAME set the image filename
@@ -135,6 +172,44 @@ optional arguments:
135
172
  -h, --help show this help message and exit
136
173
  ```
137
174
 
175
+ ### fotolab montage
176
+
177
+ ```console
178
+ fotolab montage -h
179
+ ```
180
+
181
+ ```console
182
+
183
+ usage: fotolab montage [-h] IMAGE_FILENAMES [IMAGE_FILENAMES ...]
184
+
185
+ positional arguments:
186
+ IMAGE_FILENAMES set the image filenames
187
+
188
+ optional arguments:
189
+ -h, --help show this help message and exit
190
+ ```
191
+
192
+ ### fotolab resize
193
+
194
+ ```console
195
+ fotolab resize -h
196
+ ```
197
+
198
+ ```console
199
+ usage: fotolab resize [-h] [-wh WIDTH] [-ht HEIGHT]
200
+ IMAGE_FILENAMES [IMAGE_FILENAMES ...]
201
+
202
+ positional arguments:
203
+ IMAGE_FILENAMES set the image filename
204
+
205
+ optional arguments:
206
+ -h, --help show this help message and exit
207
+ -wh WIDTH, --width WIDTH
208
+ set the width of the image (default: '600')
209
+ -ht HEIGHT, --height HEIGHT
210
+ set the height of the image (default: '277')
211
+ ```
212
+
138
213
  ### fotolab sharpen
139
214
 
140
215
  ```console
@@ -142,13 +217,22 @@ fotolab sharpen -h
142
217
  ```
143
218
 
144
219
  ```console
145
- usage: fotolab sharpen [-h] IMAGE_FILENAME
220
+ usage: fotolab sharpen [-h] [-r RADIUS] [-p PERCENT] [-t THRESHOLD]
221
+ IMAGE_FILENAMES [IMAGE_FILENAMES ...]
146
222
 
147
223
  positional arguments:
148
- IMAGE_FILENAME set the image filename
224
+ IMAGE_FILENAMES set the image filenames
149
225
 
150
- options:
151
- -h, --help show this help message and exit
226
+ optional arguments:
227
+ -h, --help show this help message and exit
228
+ -r RADIUS, --radius RADIUS
229
+ set the radius or size of edges (default: '1')
230
+ -p PERCENT, --percent PERCENT
231
+ set the amount of overall strength of sharpening
232
+ effect (default: '100')
233
+ -t THRESHOLD, --threshold THRESHOLD
234
+ set the minimum brightness changed to be sharpened
235
+ (default: '3')
152
236
  ```
153
237
 
154
238
  ### fotolab watermark
@@ -160,20 +244,23 @@ fotolab watermark -h
160
244
  ```console
161
245
  usage: fotolab watermark [-h] [-t WATERMARK_TEXT]
162
246
  [-p {top-left,top-right,bottom-left,bottom-right}]
163
- [-fs FONT_SIZE] [-fc FONT_COLOR] [-ow OUTLINE_WIDTH]
164
- [-oc OUTLINE_COLOR]
165
- IMAGE_FILENAME
247
+ [-pd PADDING] [-fs FONT_SIZE] [-fc FONT_COLOR]
248
+ [-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR]
249
+ IMAGE_FILENAMES [IMAGE_FILENAMES ...]
166
250
 
167
251
  positional arguments:
168
- IMAGE_FILENAME set the image filename
252
+ IMAGE_FILENAMES set the image filenames
169
253
 
170
- options:
254
+ optional arguments:
171
255
  -h, --help show this help message and exit
172
256
  -t WATERMARK_TEXT, --text WATERMARK_TEXT
173
257
  set the watermark text (default: 'kianmeng.org')
174
258
  -p {top-left,top-right,bottom-left,bottom-right}, --position {top-left,top-right,bottom-left,bottom-right}
175
259
  set position of the watermark text (default: 'bottom-
176
260
  left')
261
+ -pd PADDING, --padding PADDING
262
+ set the padding of the watermark text relative to the
263
+ image (default: '15')
177
264
  -fs FONT_SIZE, --font-size FONT_SIZE
178
265
  set the font size of watermark text (default: '12')
179
266
  -fc FONT_COLOR, --font-color FONT_COLOR
@@ -0,0 +1,17 @@
1
+ fotolab/__init__.py,sha256=Z3guoQD823MHOmrtHNE9W0RnI6neYdRWNCv7QTxQb6s,2074
2
+ fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
3
+ fotolab/auto.py,sha256=1Toxe8pA_tq15g1-imMFuHf1L94Ac7EthPTu7E8SAzE,2217
4
+ fotolab/border.py,sha256=5ch2d7LVPhB2OFuuXSW5ci6Cn967CPDQu0qSfaO7uMg,3591
5
+ fotolab/cli.py,sha256=KoSDb752mewrtKE5wDs9icXF2McBVOKoEB98KYAV-jQ,4570
6
+ fotolab/contrast.py,sha256=l7Bs5p8W8ypN9Cg3fFHnU-A20UwMKtjTiPk6D0PRwpM,2095
7
+ fotolab/env.py,sha256=NTTvfISWBBfIw5opWrUfg0BtkaAtdUtcISBAJC2gVUk,1449
8
+ fotolab/info.py,sha256=DawXTQJiQDBwy0Ml5Ysk8MvKga3ikp_aIw73AR3LdZo,1687
9
+ fotolab/montage.py,sha256=lUVY-zDSH7mwH-s34_XefdNp7CoDJHkwpbTUGiyJGgs,2037
10
+ fotolab/resize.py,sha256=y3JT2IZUOeWf4gjORtaJ_ZseklO2jG6XvR-d6EdhS0k,2242
11
+ fotolab/sharpen.py,sha256=DsbIe4VU0Ty5oVzKnU70p9dMfhKr1i_UAQDimzAGX-Y,2655
12
+ fotolab/watermark.py,sha256=6LeK5g6W7Gq5kpLinwqBCwFGCtp0Uz_hrqBE3BD_CEU,5210
13
+ fotolab-0.13.0.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
14
+ fotolab-0.13.0.dist-info/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
15
+ fotolab-0.13.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
16
+ fotolab-0.13.0.dist-info/METADATA,sha256=v1RC94R2HI1BVbz7dyA3nAVuGso-OsRmDZQvrHnCfuU,9085
17
+ fotolab-0.13.0.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- fotolab/__init__.py,sha256=a0NCJBRDthqiPJOuVD1dvsVwDXvm-ruruL26QiEL6q8,1237
2
- fotolab/__main__.py,sha256=aboOURPs_snOXTEWYR0q8oq1UTY9e-NxCd1j33V0wHI,833
3
- fotolab/auto.py,sha256=q_d_lOZh410nvh9yGNS3k-jg5mB0zQrhOfxSmi-nShA,2142
4
- fotolab/border.py,sha256=QBA-rJ0phv_3ace20NW18PlhLIbYDjdGVJwX13vDKdI,3776
5
- fotolab/cli.py,sha256=4IEk0DRrCPIG0PB37f4zSyWUEbrZrLSKi5qJxb1M0Is,4433
6
- fotolab/contrast.py,sha256=dtQ39YBDmBhFlRS0jB8XqLsoNGEz96ZYfgg71MyeLFg,2350
7
- fotolab/env.py,sha256=XUwy3TAFFcTMvtXAT0tLJbo-ianBo_FPK2IQfvBOhic,1400
8
- fotolab/resize.py,sha256=ax4IacQR4vuGGxGI3B-ito6ldiT054QkaKympiv4y20,2505
9
- fotolab/sharpen.py,sha256=PP1xYXupOetQxQxXijzWiUlrKNlu80lfInG37VQhVYw,2902
10
- fotolab/watermark.py,sha256=X7u-HlOONfOhU8VRyvOgIvXYUu_q9IKHBMEkIf-oem4,5031
11
- fotolab-0.9.0.dist-info/entry_points.txt,sha256=mvw7AY_yZkIyjAxPtHNed9X99NZeLnMxEeAfEJUbrCM,44
12
- fotolab-0.9.0.dist-info/LICENSE.md,sha256=tGtFDwxWTjuR9syrJoSv1Hiffd2u8Tu8cYClfrXS_YU,31956
13
- fotolab-0.9.0.dist-info/WHEEL,sha256=Sgu64hAMa6g5FdzHxXv9Xdse9yxpGGMeagVtPMWpJQY,99
14
- fotolab-0.9.0.dist-info/METADATA,sha256=i_R7skWGswlLGC1_GbZWdXWkXTup2iGeQ17iaHRZ8vc,6688
15
- fotolab-0.9.0.dist-info/RECORD,,