Skip to content

Commit c9dc553

Browse files
authored
Merge pull request #43 from huideyeren/v2.1
v2.1
2 parents a5d9067 + 5887624 commit c9dc553

File tree

13 files changed

+413
-82
lines changed

13 files changed

+413
-82
lines changed

.github/workflows/testing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
strategy:
1212
fail-fast: false
1313
matrix:
14-
python-version: ["3.10", "3.11", "3.12", "3.13"]
14+
python-version: ["3.11", "3.12", "3.13"]
1515
poetry-version: [1.8.2]
1616
os: [ubuntu-latest, macos-latest, windows-latest]
1717
runs-on: ${{ matrix.os }}

README.md

Lines changed: 183 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,142 @@ pip install anshitsu
2323
It is as described in the following help.
2424

2525
``` shell
26-
INFO: Showing help with the command 'anshitsu -- --help'.
2726

27+
28+
29+
30+
31+
32+
33+
34+
35+
36+
37+
38+
NAME
39+
main.py - Process Runnner for Command Line Interface
40+
41+
42+
SYNOPSIS
43+
main.py <flags>
44+
45+
DESCRIPTION
46+
This utility converts the colors of images such as photos.
47+
48+
If you specify a directory path, it will convert
49+
the image files in the specified directory.
50+
If you specify a file path, it will convert the specified file.
51+
If you specify an option, the specified conversion will be performed.
52+
53+
54+
Tosaka mode is a mode that expresses the preference of
55+
Tosaka-senpai, a character in "Kyūkyoku Chōjin R",
56+
for "photos taken with Tri-X that look like they were
57+
burned onto No. 4 or No. 5 photographic paper".
58+
Only use floating-point numbers when using this mode;
59+
numbers around 2.4 will make it look right.
60+
61+
FLAGS
62+
--path=PATH
63+
Type: Optional[Optional]
64+
Default: None
65+
Directory or File Path. Defaults to None.
66+
-k, --keep_alpha=KEEP_ALPHA
67+
Type: bool
68+
Default: False
69+
--colorautoadjust=COLORAUTOADJUST
70+
Type: bool
71+
Default: False
72+
Use colorautoadjust algorithm. Defaults to False.
73+
--colorstretch=COLORSTRETCH
74+
Type: bool
75+
Default: False
76+
Use colorstretch algorithm. Defaults to False.
77+
-g, --grayscale=GRAYSCALE
78+
-g, --grayscale=GRAYSCALE
79+
Type: bool
80+
Default: False
81+
Convert to grayscale. Defaults to False.
82+
-i, --invert=INVERT
83+
Type: bool
84+
Default: False
85+
Invert color. Defaults to False.
86+
--color=COLOR
87+
Type: Optional[Optional]
88+
Default: None
89+
Fix color balance. Defaults to None.
90+
-b, --brightness=BRIGHTNESS
91+
Type: Optional[Optional]
92+
Default: None
93+
Fix brightness. Defaults to None.
94+
--sharpness=SHARPNESS
95+
Type: Optional[Optional]
96+
Default: None
97+
Fix sharpness. Defaults to None.
98+
--contrast=CONTRAST
99+
Type: Optional[Optional]
100+
Default: None
101+
Fix contrast. Defaults to None.
102+
-t, --tosaka=TOSAKA
103+
Type: Optional[Optional]
104+
Default: None
105+
Convert to grayscale with fix contrast. Defaults to None.
106+
Convert to grayscale with fix contrast. Defaults to None.
107+
--outputrgb=OUTPUTRGB
108+
Type: bool
109+
Default: False
110+
Outputs a monochrome image in RGB. Defaults to False.
111+
--sepia=SEPIA
112+
Type: bool
113+
Default: False
114+
Convert to RGB colored by sepia. Defaults to False.
115+
--cyanotype=CYANOTYPE
116+
Type: bool
117+
Default: False
118+
Convert to RGB like cyanotype. Defaults to False.
119+
-n, --noise=NOISE
120+
Type: Optional[Optional]
121+
Default: None
122+
Add Gaussian noise. Defaults to None.
123+
--overwrite=OVERWRITE
124+
Type: bool
125+
Default: False
126+
Default: False
127+
--overwrite=OVERWRITE
128+
Type: Optional[Optional]
129+
Convert to RGB like cyanotype. Defaults to False.
130+
Convert to RGB colored by sepia. Defaults to False.
131+
Default: None
132+
-t, --tosaka=TOSAKA
133+
Default: None
134+
Default: None
135+
--path=PATH
136+
burned onto No. 4 or No. 5 photographic paper".
28137
NAME
29-
anshitsu - Process Runnner for Command Line Interface
138+
main.py - Process Runnner for Command Line Interface
139+
main.py - Process Runnner for Command Line Interface
30140
31141
SYNOPSIS
32-
anshitsu PATH <flags>
142+
SYNOPSIS
143+
main.py <flags>
144+
145+
146+
DESCRIPTION
147+
DESCRIPTION
148+
This utility converts the colors of images such as photos.
149+
150+
If you specify a directory path, it will convert
151+
If you specify a directory path, it will convert
152+
the image files in the specified directory.
153+
the image files in the specified directory.
154+
If you specify a file path, it will convert the specified file.
155+
If you specify an option, the specified conversion will be performed.
156+
157+
NAME
158+
main.py - Process Runnner for Command Line Interface
159+
160+
SYNOPSIS
161+
main.py <flags>
33162
34163
DESCRIPTION
35164
This utility converts the colors of images such as photos.
@@ -52,6 +181,13 @@ POSITIONAL ARGUMENTS
52181
Directory or File Path
53182
54183
FLAGS
184+
--path=PATH
185+
Type: Optional[Optional]
186+
Default: None
187+
Directory or File Path. Defaults to None.
188+
-k, --keep_alpha=KEEP_ALPHA
189+
Type: bool
190+
Default: False
55191
--colorautoadjust=COLORAUTOADJUST
56192
Type: bool
57193
Default: False
@@ -60,29 +196,65 @@ FLAGS
60196
Type: bool
61197
Default: False
62198
Use colorstretch algorithm. Defaults to False.
63-
--grayscale=GRAYSCALE
199+
-g, --grayscale=GRAYSCALE
64200
Type: bool
65201
Default: False
66202
Convert to grayscale. Defaults to False.
67-
--invert=INVERT
203+
-i, --invert=INVERT
68204
Type: bool
69205
Default: False
70206
Invert color. Defaults to False.
71-
--tosaka=TOSAKA
207+
--color=COLOR
208+
Type: Optional[Optional]
209+
Default: None
210+
Fix color balance. Defaults to None.
211+
-b, --brightness=BRIGHTNESS
212+
Type: Optional[Optional]
213+
Default: None
214+
Fix brightness. Defaults to None.
215+
--sharpness=SHARPNESS
216+
Type: Optional[Optional]
217+
Default: None
218+
Fix sharpness. Defaults to None.
219+
--contrast=CONTRAST
72220
Type: Optional[Optional]
73221
Default: None
74-
Use Tosaka mode. Defaults to None.
222+
Fix contrast. Defaults to None.
223+
-t, --tosaka=TOSAKA
224+
Type: Optional[Optional]
225+
Default: None
226+
Convert to grayscale with fix contrast. Defaults to None.
75227
--outputrgb=OUTPUTRGB
76228
Type: bool
77229
Default: False
78230
Outputs a monochrome image in RGB. Defaults to False.
79-
--noise=NOISE
231+
--sepia=SEPIA
232+
Type: bool
233+
Default: False
234+
Convert to RGB colored by sepia. Defaults to False.
235+
--cyanotype=CYANOTYPE
236+
Type: bool
237+
Default: False
238+
Convert to RGB like cyanotype. Defaults to False.
239+
-n, --noise=NOISE
80240
Type: Optional[Optional]
81241
Default: None
82242
Add Gaussian noise. Defaults to None.
83-
84-
NOTES
85-
You can also use flags syntax for POSITIONAL ARGUMENTS
243+
--overwrite=OVERWRITE
244+
Type: bool
245+
Default: False
246+
Overwrite original files. Defaults to False.
247+
-v, --version=VERSION
248+
Type: bool
249+
Default: False
250+
Show version. Defaults to False.
251+
-l, --line_drawing=LINE_DRAWING
252+
Type: bool
253+
Default: False
254+
Convert to like line drawing. Defaults to False.
255+
--posterize=POSTERIZE
256+
Type: Optional[Optional]
257+
Default: None
86258
```
87259
88260
If a directory is specified in the path, an `out` directory will be created in the specified directory, and the converted JPEG and PNG images will be stored in PNG format.

poetry.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[virtualenvs]
2+
in-project = true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "anshitsu"
3-
version = "2.0.2" # using poetry-dynamic-versioning
3+
version = "2.1.0" # using poetry-dynamic-versioning
44
description = "A tiny digital photographic utility."
55
readme = "README.md"
66
authors = ["Iosif Takakura <[email protected]>"]

src/anshitsu/cli.py

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,25 @@
1414

1515

1616
def cli(
17-
path: Optional[str] = None,
18-
colorautoadjust: bool = False,
19-
colorstretch: bool = False,
20-
grayscale: bool = False,
21-
invert: bool = False,
22-
color: Optional[float] = None,
23-
brightness: Optional[float] = None,
24-
sharpness: Optional[float] = None,
25-
contrast: Optional[float] = None,
26-
tosaka: Optional[float] = None,
27-
outputrgb: bool = False,
28-
sepia: bool = False,
29-
cyanotype: bool = False,
30-
noise: Optional[float] = None,
31-
overwrite: bool = False,
32-
version: bool = False,
33-
line_drawing: bool = False,
34-
posterize: Optional[int] = None,
17+
path: Optional[str] = None,
18+
keep_alpha: bool = False,
19+
colorautoadjust: bool = False,
20+
colorstretch: bool = False,
21+
grayscale: bool = False,
22+
invert: bool = False,
23+
color: Optional[float] = None,
24+
brightness: Optional[float] = None,
25+
sharpness: Optional[float] = None,
26+
contrast: Optional[float] = None,
27+
tosaka: Optional[float] = None,
28+
outputrgb: bool = False,
29+
sepia: bool = False,
30+
cyanotype: bool = False,
31+
noise: Optional[float] = None,
32+
overwrite: bool = False,
33+
version: bool = False,
34+
line_drawing: bool = False,
35+
posterize: Optional[int] = None,
3536
) -> str:
3637
"""
3738
Process Runnner for Command Line Interface
@@ -87,7 +88,7 @@ def cli(
8788
original_dir = "anshitsu_orig"
8889
if os.path.isdir(path):
8990
for type in types:
90-
files_glob.extend(glob.glob(os.path.join(path, '**', type), recursive=True))
91+
files_glob.extend(glob.glob(os.path.join(path, "**", type), recursive=True))
9192
files_glob = [file for file in files_glob if not file.__contains__(output_dir)]
9293
return_path = path
9394

@@ -113,15 +114,15 @@ def cli(
113114
timestamp = now_s.strftime("%Y-%m-%d_%H-%M-%S")
114115
if overwrite is True:
115116
backup_filename = original_filename
116-
image.save(os.path.join(
117-
return_path,
118-
original_dir,
119-
backup_filename
120-
))
121-
filename = os.path.join(return_path, re.sub(r"\.[^.]+$", "", original_filename) + ".png")
117+
image.save(os.path.join(return_path, original_dir, backup_filename))
118+
filename = os.path.join(
119+
return_path, re.sub(r"\.[^.]+$", "", original_filename) + ".png"
120+
)
122121
remove_file_list = [".jpg", ".JPG", ".jpeg", ".JPEG", ".PNG"]
123122
for remove_file in remove_file_list:
124-
remove_file_name = re.sub(r"\.[^.]+$", "", original_filename) + remove_file
123+
remove_file_name = (
124+
re.sub(r"\.[^.]+$", "", original_filename) + remove_file
125+
)
125126
remove_file_path = os.path.join(return_path, remove_file_name)
126127
if os.path.isfile(remove_file_path):
127128
os.remove(remove_file_path)
@@ -130,9 +131,11 @@ def cli(
130131
return_path,
131132
output_dir,
132133
re.sub(r"\.[^.]+$", "_", original_filename)
133-
+ "_{0}_converted_at_{1}.png".format(extension, timestamp))
134+
+ "_{0}_converted_at_{1}.png".format(extension, timestamp),
135+
)
134136
psr = Processor(
135137
image=image,
138+
keep_alpha=keep_alpha,
136139
colorautoadjust=colorautoadjust,
137140
colorstretch=colorstretch,
138141
grayscale=grayscale,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from typing import Union
2+
3+
from PIL import Image
4+
5+
6+
def create_alpha_mask(image: Image) -> Union[Image, None]:
7+
"""
8+
create_alpha_mask
9+
10+
If image has alpha layer, create alpha mask.
11+
12+
Parameters:
13+
image: Image
14+
15+
Returns:
16+
Image: cutout alpha mask.
17+
None: Image has not alpha mask.
18+
"""
19+
if image.mode == "RGBA":
20+
_, _, _, alpha = image.split()
21+
alpha_channel = 255
22+
alpha.paste(Image.new("L", image.size, alpha_channel), mask=alpha)
23+
return alpha
24+
elif image.mode == "LA":
25+
_, alpha = image.split()
26+
alpha_channel = 255
27+
alpha.paste(Image.new("L", image.size, alpha_channel), mask=alpha)
28+
return alpha
29+
else:
30+
return None

src/anshitsu/process/line_drawing.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33

44
def line_drawing(image: Image, invert: bool) -> Image:
5+
"""
6+
line_drawing
7+
8+
Paint like line drawing on an image.
9+
If invert is True, the image will be inverted.
10+
11+
Parameters:
12+
image: Image
13+
invert: bool
14+
15+
Returns:
16+
Image: processed image.
17+
"""
518
image = image.convert("L")
619
img_filter = image.filter(ImageFilter.MaxFilter(5))
720
line_draw = ImageChops.difference(image, img_filter)

0 commit comments

Comments
 (0)