fotolab 0.18.4__tar.gz → 0.20.0__tar.gz

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.
Files changed (42) hide show
  1. {fotolab-0.18.4 → fotolab-0.20.0}/CHANGELOG.md +12 -0
  2. {fotolab-0.18.4 → fotolab-0.20.0}/PKG-INFO +38 -40
  3. {fotolab-0.18.4 → fotolab-0.20.0}/Pipfile.lock +10 -10
  4. {fotolab-0.18.4 → fotolab-0.20.0}/README.md +37 -39
  5. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/__init__.py +1 -1
  6. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/auto.py +1 -0
  7. fotolab-0.20.0/fotolab/resize.py +176 -0
  8. fotolab-0.18.4/fotolab/resize.py +0 -116
  9. {fotolab-0.18.4 → fotolab-0.20.0}/.coveragerc +0 -0
  10. {fotolab-0.18.4 → fotolab-0.20.0}/.gitignore +0 -0
  11. {fotolab-0.18.4 → fotolab-0.20.0}/.pre-commit-config.yaml +0 -0
  12. {fotolab-0.18.4 → fotolab-0.20.0}/.python-version +0 -0
  13. {fotolab-0.18.4 → fotolab-0.20.0}/CONTRIBUTING.md +0 -0
  14. {fotolab-0.18.4 → fotolab-0.20.0}/LICENSE.md +0 -0
  15. {fotolab-0.18.4 → fotolab-0.20.0}/Pipfile +0 -0
  16. {fotolab-0.18.4 → fotolab-0.20.0}/docs/Makefile +0 -0
  17. {fotolab-0.18.4 → fotolab-0.20.0}/docs/make.bat +0 -0
  18. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/CHANGELOG.md +0 -0
  19. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/CONTRIBUTING.md +0 -0
  20. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/LICENSE.md +0 -0
  21. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/README.md +0 -0
  22. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/_static/logo.jpg +0 -0
  23. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/conf.py +0 -0
  24. {fotolab-0.18.4 → fotolab-0.20.0}/docs/source/index.rst +0 -0
  25. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/__main__.py +0 -0
  26. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/animate.py +0 -0
  27. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/border.py +0 -0
  28. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/cli.py +0 -0
  29. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/contrast.py +0 -0
  30. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/env.py +0 -0
  31. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/info.py +0 -0
  32. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/montage.py +0 -0
  33. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/rotate.py +0 -0
  34. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/sharpen.py +0 -0
  35. {fotolab-0.18.4 → fotolab-0.20.0}/fotolab/watermark.py +0 -0
  36. {fotolab-0.18.4 → fotolab-0.20.0}/noxfile.py +0 -0
  37. {fotolab-0.18.4 → fotolab-0.20.0}/pyproject.toml +0 -0
  38. {fotolab-0.18.4 → fotolab-0.20.0}/tests/__init__.py +0 -0
  39. {fotolab-0.18.4 → fotolab-0.20.0}/tests/conftest.py +0 -0
  40. {fotolab-0.18.4 → fotolab-0.20.0}/tests/test_env.py +0 -0
  41. {fotolab-0.18.4 → fotolab-0.20.0}/tests/test_help_flag.py +0 -0
  42. {fotolab-0.18.4 → fotolab-0.20.0}/tests/test_quiet_flag.py +0 -0
@@ -7,6 +7,18 @@ and this project adheres to [0-based versioning](https://0ver.org/).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## v0.20.0 (2024-11-10)
11
+
12
+ - Add `-l` or `--canvas-color` option to set color to extended canvas
13
+ - Bump deps
14
+ - Update help message in readme
15
+
16
+ ## v0.19.0 (2024-11-03)
17
+
18
+ - Add `-c` or `--canvas` flag to paste an image onto larger canvas
19
+ - Bump deps
20
+ - Require both length and height when `--canvas` flag is toggled
21
+
10
22
  ## v0.18.4 (2024-10-27)
11
23
 
12
24
  - Bump deps and `pre-commit` hooks
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fotolab
3
- Version: 0.18.4
3
+ Version: 0.20.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>
@@ -60,14 +60,13 @@ fotolab -h
60
60
 
61
61
  ```console
62
62
  usage: fotolab [-h] [-o] [-op] [-od OUTPUT_DIR] [-q] [-v] [-d] [-V]
63
- {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env}
64
- ...
63
+ {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env} ...
65
64
 
66
65
  A console program to manipulate photos.
67
66
 
68
- website: https://github.com/kianmeng/fotolab
69
- changelog: https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
70
- issues: https://github.com/kianmeng/fotolab/issues
67
+ website: https://github.com/kianmeng/fotolab
68
+ changelog: https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
69
+ issues: https://github.com/kianmeng/fotolab/issues
71
70
 
72
71
  positional arguments:
73
72
  {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env}
@@ -88,7 +87,7 @@ options:
88
87
  -h, --help show this help message and exit
89
88
  -o, --overwrite overwrite existing image
90
89
  -op, --open open the image using default program (default: 'False')
91
- -od OUTPUT_DIR, --output-dir OUTPUT_DIR
90
+ -od, --output-dir OUTPUT_DIR
92
91
  set default output folder (default: 'output')
93
92
  -q, --quiet suppress all logging
94
93
  -v, --verbose show verbosity of debugging log, use -vv, -vvv for more details
@@ -115,11 +114,10 @@ positional arguments:
115
114
 
116
115
  options:
117
116
  -h, --help show this help message and exit
118
- -f FORMAT, --format FORMAT
119
- set the image format (default: 'gif')
120
- -d DURATION, --duration DURATION
117
+ -f, --format FORMAT set the image format (default: 'gif')
118
+ -d, --duration DURATION
121
119
  set the duration in milliseconds (default: '2500')
122
- -l LOOP, --loop LOOP set the loop cycle (default: '0')
120
+ -l, --loop LOOP set the loop cycle (default: '0')
123
121
  ```
124
122
 
125
123
  <!--help-animate !-->
@@ -162,17 +160,15 @@ positional arguments:
162
160
 
163
161
  options:
164
162
  -h, --help show this help message and exit
165
- -c COLOR, --color COLOR
166
- set the color of border (default: 'black')
167
- -w WIDTH, --width WIDTH
168
- set the width of border (default: '10')
169
- -wt WIDTH, --width-top WIDTH
163
+ -c, --color COLOR set the color of border (default: 'black')
164
+ -w, --width WIDTH set the width of border (default: '10')
165
+ -wt, --width-top WIDTH
170
166
  set the width of top border (default: '0')
171
- -wr WIDTH, --width-right WIDTH
167
+ -wr, --width-right WIDTH
172
168
  set the width of right border (default: '0')
173
- -wb WIDTH, --width-bottom WIDTH
169
+ -wb, --width-bottom WIDTH
174
170
  set the width of bottom border (default: '0')
175
- -wl WIDTH, --width-left WIDTH
171
+ -wl, --width-left WIDTH
176
172
  set the width of left border (default: '0')
177
173
  ```
178
174
 
@@ -190,13 +186,12 @@ fotolab contrast -h
190
186
  usage: fotolab contrast [-h] [-c CUTOFF] IMAGE_FILENAMES [IMAGE_FILENAMES ...]
191
187
 
192
188
  positional arguments:
193
- IMAGE_FILENAMES set the image filename
189
+ IMAGE_FILENAMES set the image filename
194
190
 
195
191
  options:
196
- -h, --help show this help message and exit
197
- -c CUTOFF, --cutoff CUTOFF
198
- set the percentage of lightest or darkest pixels to
199
- discard from histogram (default: '1')
192
+ -h, --help show this help message and exit
193
+ -c, --cutoff CUTOFF set the percentage of lightest or darkest pixels to
194
+ discard from histogram (default: '1')
200
195
  ```
201
196
 
202
197
  <!--help-contrast !-->
@@ -271,7 +266,7 @@ fotolab resize -h
271
266
  <!--help-resize !-->
272
267
 
273
268
  ```console
274
- usage: fotolab resize [-h] [-wh WIDTH | -ht HEIGHT]
269
+ usage: fotolab resize [-h] [-c] [-l CANVAS_COLOR] [-W WIDTH | -H HEIGHT]
275
270
  IMAGE_FILENAMES [IMAGE_FILENAMES ...]
276
271
 
277
272
  positional arguments:
@@ -279,10 +274,12 @@ positional arguments:
279
274
 
280
275
  options:
281
276
  -h, --help show this help message and exit
282
- -wh WIDTH, --width WIDTH
283
- set the width of the image (default: '600')
284
- -ht HEIGHT, --height HEIGHT
285
- set the height of the image (default: '277')
277
+ -c, --canvas paste image onto a larger canvas
278
+ -l, --canvas-color CANVAS_COLOR
279
+ the color of the extended larger canvas(default:
280
+ 'black')
281
+ -W, --width WIDTH set the width of the image (default: '600')
282
+ -H, --height HEIGHT set the height of the image (default: '277')
286
283
  ```
287
284
 
288
285
  <!--help-resize !-->
@@ -304,12 +301,11 @@ positional arguments:
304
301
 
305
302
  options:
306
303
  -h, --help show this help message and exit
307
- -r RADIUS, --radius RADIUS
308
- set the radius or size of edges (default: '1')
309
- -p PERCENT, --percent PERCENT
304
+ -r, --radius RADIUS set the radius or size of edges (default: '1')
305
+ -p, --percent PERCENT
310
306
  set the amount of overall strength of sharpening
311
307
  effect (default: '100')
312
- -t THRESHOLD, --threshold THRESHOLD
308
+ -t, --threshold THRESHOLD
313
309
  set the minimum brightness changed to be sharpened
314
310
  (default: '3')
315
311
  ```
@@ -329,6 +325,7 @@ usage: fotolab watermark [-h] [-t WATERMARK_TEXT]
329
325
  [-p {top-left,top-right,bottom-left,bottom-right}]
330
326
  [-pd PADDING] [-fs FONT_SIZE] [-fc FONT_COLOR]
331
327
  [-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR] [--camera]
328
+ [-l]
332
329
  IMAGE_FILENAMES [IMAGE_FILENAMES ...]
333
330
 
334
331
  positional arguments:
@@ -336,26 +333,27 @@ positional arguments:
336
333
 
337
334
  options:
338
335
  -h, --help show this help message and exit
339
- -t WATERMARK_TEXT, --text WATERMARK_TEXT
336
+ -t, --text WATERMARK_TEXT
340
337
  set the watermark text (default: 'kianmeng.org')
341
- -p {top-left,top-right,bottom-left,bottom-right}, --position {top-left,top-right,bottom-left,bottom-right}
338
+ -p, --position {top-left,top-right,bottom-left,bottom-right}
342
339
  set position of the watermark text (default: 'bottom-
343
340
  left')
344
- -pd PADDING, --padding PADDING
341
+ -pd, --padding PADDING
345
342
  set the padding of the watermark text relative to the
346
343
  image (default: '15')
347
- -fs FONT_SIZE, --font-size FONT_SIZE
344
+ -fs, --font-size FONT_SIZE
348
345
  set the font size of watermark text (default: '12')
349
- -fc FONT_COLOR, --font-color FONT_COLOR
346
+ -fc, --font-color FONT_COLOR
350
347
  set the font color of watermark text (default:
351
348
  'white')
352
- -ow OUTLINE_WIDTH, --outline-width OUTLINE_WIDTH
349
+ -ow, --outline-width OUTLINE_WIDTH
353
350
  set the outline width of the watermark text (default:
354
351
  '2')
355
- -oc OUTLINE_COLOR, --outline-color OUTLINE_COLOR
352
+ -oc, --outline-color OUTLINE_COLOR
356
353
  set the outline color of the watermark text (default:
357
354
  'black')
358
355
  --camera use camera metadata as watermark
356
+ -l, --lowercase lowercase the watermark text
359
357
  ```
360
358
 
361
359
  <!--help-watermark !-->
@@ -261,11 +261,11 @@
261
261
  },
262
262
  "colorlog": {
263
263
  "hashes": [
264
- "sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44",
265
- "sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33"
264
+ "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff",
265
+ "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2"
266
266
  ],
267
267
  "markers": "python_version >= '3.6'",
268
- "version": "==6.8.2"
268
+ "version": "==6.9.0"
269
269
  },
270
270
  "coverage": {
271
271
  "extras": [
@@ -766,12 +766,12 @@
766
766
  },
767
767
  "pytest-cov": {
768
768
  "hashes": [
769
- "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652",
770
- "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"
769
+ "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35",
770
+ "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"
771
771
  ],
772
772
  "index": "pypi",
773
- "markers": "python_version >= '3.8'",
774
- "version": "==5.0.0"
773
+ "markers": "python_version >= '3.9'",
774
+ "version": "==6.0.0"
775
775
  },
776
776
  "pytest-randomly": {
777
777
  "hashes": [
@@ -966,11 +966,11 @@
966
966
  },
967
967
  "virtualenv": {
968
968
  "hashes": [
969
- "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2",
970
- "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"
969
+ "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba",
970
+ "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"
971
971
  ],
972
972
  "markers": "python_version >= '3.8'",
973
- "version": "==20.27.0"
973
+ "version": "==20.27.1"
974
974
  },
975
975
  "zipp": {
976
976
  "hashes": [
@@ -38,14 +38,13 @@ fotolab -h
38
38
 
39
39
  ```console
40
40
  usage: fotolab [-h] [-o] [-op] [-od OUTPUT_DIR] [-q] [-v] [-d] [-V]
41
- {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env}
42
- ...
41
+ {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env} ...
43
42
 
44
43
  A console program to manipulate photos.
45
44
 
46
- website: https://github.com/kianmeng/fotolab
47
- changelog: https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
48
- issues: https://github.com/kianmeng/fotolab/issues
45
+ website: https://github.com/kianmeng/fotolab
46
+ changelog: https://github.com/kianmeng/fotolab/blob/master/CHANGELOG.md
47
+ issues: https://github.com/kianmeng/fotolab/issues
49
48
 
50
49
  positional arguments:
51
50
  {animate,auto,border,contrast,info,resize,rotate,montage,sharpen,watermark,env}
@@ -66,7 +65,7 @@ options:
66
65
  -h, --help show this help message and exit
67
66
  -o, --overwrite overwrite existing image
68
67
  -op, --open open the image using default program (default: 'False')
69
- -od OUTPUT_DIR, --output-dir OUTPUT_DIR
68
+ -od, --output-dir OUTPUT_DIR
70
69
  set default output folder (default: 'output')
71
70
  -q, --quiet suppress all logging
72
71
  -v, --verbose show verbosity of debugging log, use -vv, -vvv for more details
@@ -93,11 +92,10 @@ positional arguments:
93
92
 
94
93
  options:
95
94
  -h, --help show this help message and exit
96
- -f FORMAT, --format FORMAT
97
- set the image format (default: 'gif')
98
- -d DURATION, --duration DURATION
95
+ -f, --format FORMAT set the image format (default: 'gif')
96
+ -d, --duration DURATION
99
97
  set the duration in milliseconds (default: '2500')
100
- -l LOOP, --loop LOOP set the loop cycle (default: '0')
98
+ -l, --loop LOOP set the loop cycle (default: '0')
101
99
  ```
102
100
 
103
101
  <!--help-animate !-->
@@ -140,17 +138,15 @@ positional arguments:
140
138
 
141
139
  options:
142
140
  -h, --help show this help message and exit
143
- -c COLOR, --color COLOR
144
- set the color of border (default: 'black')
145
- -w WIDTH, --width WIDTH
146
- set the width of border (default: '10')
147
- -wt WIDTH, --width-top WIDTH
141
+ -c, --color COLOR set the color of border (default: 'black')
142
+ -w, --width WIDTH set the width of border (default: '10')
143
+ -wt, --width-top WIDTH
148
144
  set the width of top border (default: '0')
149
- -wr WIDTH, --width-right WIDTH
145
+ -wr, --width-right WIDTH
150
146
  set the width of right border (default: '0')
151
- -wb WIDTH, --width-bottom WIDTH
147
+ -wb, --width-bottom WIDTH
152
148
  set the width of bottom border (default: '0')
153
- -wl WIDTH, --width-left WIDTH
149
+ -wl, --width-left WIDTH
154
150
  set the width of left border (default: '0')
155
151
  ```
156
152
 
@@ -168,13 +164,12 @@ fotolab contrast -h
168
164
  usage: fotolab contrast [-h] [-c CUTOFF] IMAGE_FILENAMES [IMAGE_FILENAMES ...]
169
165
 
170
166
  positional arguments:
171
- IMAGE_FILENAMES set the image filename
167
+ IMAGE_FILENAMES set the image filename
172
168
 
173
169
  options:
174
- -h, --help show this help message and exit
175
- -c CUTOFF, --cutoff CUTOFF
176
- set the percentage of lightest or darkest pixels to
177
- discard from histogram (default: '1')
170
+ -h, --help show this help message and exit
171
+ -c, --cutoff CUTOFF set the percentage of lightest or darkest pixels to
172
+ discard from histogram (default: '1')
178
173
  ```
179
174
 
180
175
  <!--help-contrast !-->
@@ -249,7 +244,7 @@ fotolab resize -h
249
244
  <!--help-resize !-->
250
245
 
251
246
  ```console
252
- usage: fotolab resize [-h] [-wh WIDTH | -ht HEIGHT]
247
+ usage: fotolab resize [-h] [-c] [-l CANVAS_COLOR] [-W WIDTH | -H HEIGHT]
253
248
  IMAGE_FILENAMES [IMAGE_FILENAMES ...]
254
249
 
255
250
  positional arguments:
@@ -257,10 +252,12 @@ positional arguments:
257
252
 
258
253
  options:
259
254
  -h, --help show this help message and exit
260
- -wh WIDTH, --width WIDTH
261
- set the width of the image (default: '600')
262
- -ht HEIGHT, --height HEIGHT
263
- set the height of the image (default: '277')
255
+ -c, --canvas paste image onto a larger canvas
256
+ -l, --canvas-color CANVAS_COLOR
257
+ the color of the extended larger canvas(default:
258
+ 'black')
259
+ -W, --width WIDTH set the width of the image (default: '600')
260
+ -H, --height HEIGHT set the height of the image (default: '277')
264
261
  ```
265
262
 
266
263
  <!--help-resize !-->
@@ -282,12 +279,11 @@ positional arguments:
282
279
 
283
280
  options:
284
281
  -h, --help show this help message and exit
285
- -r RADIUS, --radius RADIUS
286
- set the radius or size of edges (default: '1')
287
- -p PERCENT, --percent PERCENT
282
+ -r, --radius RADIUS set the radius or size of edges (default: '1')
283
+ -p, --percent PERCENT
288
284
  set the amount of overall strength of sharpening
289
285
  effect (default: '100')
290
- -t THRESHOLD, --threshold THRESHOLD
286
+ -t, --threshold THRESHOLD
291
287
  set the minimum brightness changed to be sharpened
292
288
  (default: '3')
293
289
  ```
@@ -307,6 +303,7 @@ usage: fotolab watermark [-h] [-t WATERMARK_TEXT]
307
303
  [-p {top-left,top-right,bottom-left,bottom-right}]
308
304
  [-pd PADDING] [-fs FONT_SIZE] [-fc FONT_COLOR]
309
305
  [-ow OUTLINE_WIDTH] [-oc OUTLINE_COLOR] [--camera]
306
+ [-l]
310
307
  IMAGE_FILENAMES [IMAGE_FILENAMES ...]
311
308
 
312
309
  positional arguments:
@@ -314,26 +311,27 @@ positional arguments:
314
311
 
315
312
  options:
316
313
  -h, --help show this help message and exit
317
- -t WATERMARK_TEXT, --text WATERMARK_TEXT
314
+ -t, --text WATERMARK_TEXT
318
315
  set the watermark text (default: 'kianmeng.org')
319
- -p {top-left,top-right,bottom-left,bottom-right}, --position {top-left,top-right,bottom-left,bottom-right}
316
+ -p, --position {top-left,top-right,bottom-left,bottom-right}
320
317
  set position of the watermark text (default: 'bottom-
321
318
  left')
322
- -pd PADDING, --padding PADDING
319
+ -pd, --padding PADDING
323
320
  set the padding of the watermark text relative to the
324
321
  image (default: '15')
325
- -fs FONT_SIZE, --font-size FONT_SIZE
322
+ -fs, --font-size FONT_SIZE
326
323
  set the font size of watermark text (default: '12')
327
- -fc FONT_COLOR, --font-color FONT_COLOR
324
+ -fc, --font-color FONT_COLOR
328
325
  set the font color of watermark text (default:
329
326
  'white')
330
- -ow OUTLINE_WIDTH, --outline-width OUTLINE_WIDTH
327
+ -ow, --outline-width OUTLINE_WIDTH
331
328
  set the outline width of the watermark text (default:
332
329
  '2')
333
- -oc OUTLINE_COLOR, --outline-color OUTLINE_COLOR
330
+ -oc, --outline-color OUTLINE_COLOR
334
331
  set the outline color of the watermark text (default:
335
332
  'black')
336
333
  --camera use camera metadata as watermark
334
+ -l, --lowercase lowercase the watermark text
337
335
  ```
338
336
 
339
337
  <!--help-watermark !-->
@@ -21,7 +21,7 @@ import subprocess
21
21
  import sys
22
22
  from pathlib import Path
23
23
 
24
- __version__ = "0.18.4"
24
+ __version__ = "0.20.0"
25
25
 
26
26
  log = logging.getLogger(__name__)
27
27
 
@@ -68,6 +68,7 @@ def run(args: argparse.Namespace) -> None:
68
68
  "outline_color": "black",
69
69
  "padding": 15,
70
70
  "camera": False,
71
+ "canvas": False,
71
72
  "lowercase": False,
72
73
  }
73
74
  combined_args = argparse.Namespace(**vars(args), **extra_args)
@@ -0,0 +1,176 @@
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
+ """Resize subcommand."""
17
+
18
+ import argparse
19
+ import logging
20
+ import math
21
+ import sys
22
+
23
+ from PIL import Image, ImageColor
24
+
25
+ from fotolab import save_image
26
+
27
+ log = logging.getLogger(__name__)
28
+
29
+ DEFAULT_WIDTH = 600
30
+ DEFAULT_HEIGHT = 277
31
+
32
+
33
+ def build_subparser(subparsers) -> None:
34
+ """Build the subparser."""
35
+ resize_parser = subparsers.add_parser("resize", help="resize an image")
36
+
37
+ resize_parser.set_defaults(func=run)
38
+
39
+ resize_parser.add_argument(
40
+ dest="image_filenames",
41
+ help="set the image filename",
42
+ nargs="+",
43
+ type=str,
44
+ default=None,
45
+ metavar="IMAGE_FILENAMES",
46
+ )
47
+
48
+ resize_parser.add_argument(
49
+ "-c",
50
+ "--canvas",
51
+ default=False,
52
+ action="store_true",
53
+ dest="canvas",
54
+ help="paste image onto a larger canvas",
55
+ )
56
+
57
+ resize_parser.add_argument(
58
+ "-l",
59
+ "--canvas-color",
60
+ default="black",
61
+ dest="canvas_color",
62
+ help=(
63
+ "the color of the extended larger canvas"
64
+ "(default: '%(default)s')"
65
+ ),
66
+ )
67
+
68
+ if "-c" in sys.argv or "--canvas" in sys.argv:
69
+ resize_parser.add_argument(
70
+ "-W",
71
+ "--width",
72
+ dest="width",
73
+ help="set the width of the image (default: '%(default)s')",
74
+ type=int,
75
+ required=True,
76
+ metavar="WIDTH",
77
+ )
78
+
79
+ resize_parser.add_argument(
80
+ "-H",
81
+ "--height",
82
+ dest="height",
83
+ help="set the height of the image (default: '%(default)s')",
84
+ type=int,
85
+ required=True,
86
+ metavar="HEIGHT",
87
+ )
88
+ else:
89
+ group = resize_parser.add_mutually_exclusive_group(required=False)
90
+
91
+ group.add_argument(
92
+ "-W",
93
+ "--width",
94
+ dest="width",
95
+ help="set the width of the image (default: '%(default)s')",
96
+ type=int,
97
+ default=DEFAULT_WIDTH,
98
+ metavar="WIDTH",
99
+ )
100
+
101
+ group.add_argument(
102
+ "-H",
103
+ "--height",
104
+ dest="height",
105
+ help="set the height of the image (default: '%(default)s')",
106
+ type=int,
107
+ default=DEFAULT_HEIGHT,
108
+ metavar="HEIGHT",
109
+ )
110
+
111
+
112
+ def run(args: argparse.Namespace) -> None:
113
+ """Run resize subcommand.
114
+
115
+ Args:
116
+ args (argparse.Namespace): Config from command line arguments
117
+
118
+ Returns:
119
+ None
120
+ """
121
+ log.debug(args)
122
+
123
+ for image_filename in args.image_filenames:
124
+ original_image = Image.open(image_filename)
125
+ if args.canvas:
126
+ resized_image = _resize_image_onto_canvas(original_image, args)
127
+ else:
128
+ resized_image = _resize_image(original_image, args)
129
+ save_image(args, resized_image, image_filename, "resize")
130
+
131
+
132
+ def _resize_image_onto_canvas(original_image, args):
133
+ resized_image = Image.new(
134
+ "RGB",
135
+ (args.width, args.height),
136
+ (*ImageColor.getrgb(args.canvas_color), 128),
137
+ )
138
+ x_offset = (args.width - original_image.width) // 2
139
+ y_offset = (args.height - original_image.height) // 2
140
+ resized_image.paste(original_image, (x_offset, y_offset))
141
+ return resized_image
142
+
143
+
144
+ def _resize_image(original_image, args):
145
+ new_width, new_height = _calc_new_image_dimension(original_image, args)
146
+ resized_image = original_image.copy()
147
+ resized_image = resized_image.resize(
148
+ (new_width, new_height), Image.Resampling.LANCZOS
149
+ )
150
+ return resized_image
151
+
152
+
153
+ def _calc_new_image_dimension(image, args) -> tuple:
154
+ new_width = args.width
155
+ new_height = args.height
156
+
157
+ old_width, old_height = image.size
158
+ log.debug("old image dimension: %d x %d", old_width, old_height)
159
+
160
+ if args.width != DEFAULT_WIDTH:
161
+ aspect_ratio = old_height / old_width
162
+ log.debug("aspect ratio: %f", aspect_ratio)
163
+
164
+ new_height = math.ceil(args.width * aspect_ratio)
165
+ log.debug("new height: %d", new_height)
166
+
167
+ if args.height != DEFAULT_HEIGHT:
168
+ aspect_ratio = old_width / old_height
169
+ log.debug("aspect ratio: %f", aspect_ratio)
170
+
171
+ new_width = math.floor(args.height * aspect_ratio)
172
+ log.debug("new width: %d", new_width)
173
+
174
+ log.debug("new image dimension: %d x %d", new_width, new_height)
175
+
176
+ return (new_width, new_height)
@@ -1,116 +0,0 @@
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
- """Resize subcommand."""
17
-
18
- import argparse
19
- import logging
20
- import math
21
-
22
- from PIL import Image
23
-
24
- from fotolab import save_image
25
-
26
- log = logging.getLogger(__name__)
27
-
28
- DEFAULT_WIDTH = 600
29
- DEFAULT_HEIGHT = 277
30
-
31
-
32
- def build_subparser(subparsers) -> None:
33
- """Build the subparser."""
34
- resize_parser = subparsers.add_parser("resize", help="resize an image")
35
-
36
- resize_parser.set_defaults(func=run)
37
-
38
- resize_parser.add_argument(
39
- dest="image_filenames",
40
- help="set the image filename",
41
- nargs="+",
42
- type=str,
43
- default=None,
44
- metavar="IMAGE_FILENAMES",
45
- )
46
-
47
- group = resize_parser.add_mutually_exclusive_group(required=False)
48
-
49
- group.add_argument(
50
- "-wh",
51
- "--width",
52
- dest="width",
53
- help="set the width of the image (default: '%(default)s')",
54
- type=int,
55
- default=DEFAULT_WIDTH,
56
- metavar="WIDTH",
57
- )
58
-
59
- group.add_argument(
60
- "-ht",
61
- "--height",
62
- dest="height",
63
- help="set the height of the image (default: '%(default)s')",
64
- type=int,
65
- default=DEFAULT_HEIGHT,
66
- metavar="HEIGHT",
67
- )
68
-
69
-
70
- def run(args: argparse.Namespace) -> None:
71
- """Run resize subcommand.
72
-
73
- Args:
74
- args (argparse.Namespace): Config from command line arguments
75
-
76
- Returns:
77
- None
78
- """
79
- log.debug(args)
80
-
81
- for image_filename in args.image_filenames:
82
- original_image = Image.open(image_filename)
83
-
84
- new_width, new_height = _calc_new_image_dimension(original_image, args)
85
- resized_image = original_image.copy()
86
- resized_image = resized_image.resize(
87
- (new_width, new_height), Image.Resampling.LANCZOS
88
- )
89
-
90
- save_image(args, resized_image, image_filename, "resize")
91
-
92
-
93
- def _calc_new_image_dimension(image, args) -> tuple:
94
- new_width = args.width
95
- new_height = args.height
96
-
97
- old_width, old_height = image.size
98
- log.debug("old image dimension: %d x %d", old_width, old_height)
99
-
100
- if args.width != DEFAULT_WIDTH:
101
- aspect_ratio = old_height / old_width
102
- log.debug("aspect ratio: %f", aspect_ratio)
103
-
104
- new_height = math.ceil(args.width * aspect_ratio)
105
- log.debug("new height: %d", new_height)
106
-
107
- if args.height != DEFAULT_HEIGHT:
108
- aspect_ratio = old_width / old_height
109
- log.debug("aspect ratio: %f", aspect_ratio)
110
-
111
- new_width = math.floor(args.height * aspect_ratio)
112
- log.debug("new width: %d", new_width)
113
-
114
- log.debug("new image dimension: %d x %d", new_width, new_height)
115
-
116
- return (new_width, new_height)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes