Skip to content

Commit 95c04f3

Browse files
committed
Add filters new filters pop and simple
1 parent 8ee99c8 commit 95c04f3

File tree

6 files changed

+248
-71
lines changed

6 files changed

+248
-71
lines changed

.github/workflows/action.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: GitHub Action
2+
on:
3+
push:
4+
pull_request:
5+
workflow_dispatch:
6+
jobs:
7+
lint:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Set up Python
12+
uses: actions/setup-python@v2
13+
with:
14+
python-version: 3.6.9
15+
- name: Install dependencies
16+
run: |
17+
python -m pip install --upgrade pip
18+
pip install flake8
19+
pip install pylint
20+
- name: Lint with flake8
21+
run: |
22+
flake8 python_fu_cartoonify.py --count --select=E9,F63,F7,F82 --show-source --statistics
23+
flake8 python_fu_cartoonify.py --count --max-complexity=10 --max-line-length=79 --statistics
24+
- name: Lint with Pylint
25+
run: |
26+
pylint python_fu_cartoonify.py

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Changelog
2+
## 1.1.0 - January 11, 2022
3+
* Add filter `Pop`
4+
* Add filter `Simple`
5+
6+
## 1.0.0 - January 3, 2022
7+
* Add filter `Realistic`

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# python-fu-cartoonify
2-
GIMP plug-in to turn a photo into a cartoon.
2+
A set of GIMP plug-ins to turn a photo into a cartoon.
33

44
## Preview
55
![Preview](images/preview.jpg)
66

77
# Installation
8-
1. Copy `python-fu-cartoonify.py` into the plug-in folder listed under `Edit > Preferences > Folders > Plug-ins`.
8+
1. Copy `python_fu_cartoonify.py` into the plug-in folder listed under `Edit > Preferences > Folders > Plug-ins`.
99
1. On unix ensure the file can be executed as program.
10-
1. Restart GIMP, the plug-in is listed under `Filters > Artistic > Cartoonify...`
10+
1. Restart GIMP, the plug-ins are listed under `Filters > Artistic > Cartoonify`
1111

1212
# License
1313
python-fu-cartoonify is licensed under the [GPL-3.0 License](https://raw.githubusercontent.com/pascalre/python-fu-cartoonify/master/LICENSE).

images/preview.jpg

8.51 MB
Loading

python-fu-cartoonify.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

python_fu_cartoonify.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
"""A set of GIMP plug-ins to turn a photo into a cartoon."""
4+
5+
from gimpfu import pdb, register, main, PF_IMAGE, PF_DRAWABLE,\
6+
PF_ADJUSTMENT # pylint: disable=import-error
7+
8+
9+
def copy_layer(img, drawable, name, tattoo):
10+
"""Copy a layer, set name and tattoo."""
11+
layer = pdb.gimp_layer_copy(drawable, False)
12+
pdb.gimp_image_add_layer(img, layer, -1)
13+
pdb.gimp_item_set_name(layer, name)
14+
pdb.gimp_item_set_tattoo(layer, tattoo)
15+
return layer
16+
17+
18+
def merge_down_with_mode(img, layer, mode):
19+
"""Apply mode to layer and merge it down."""
20+
pdb.gimp_layer_set_mode(layer, mode)
21+
pdb.gimp_image_merge_down(img, layer, 0)
22+
23+
24+
def cartoonify_pop(img, drawable, line_size, shadow_intensity, color_levels):
25+
"""Apply carton filter 'pop' to a given image."""
26+
pdb.gimp_image_undo_group_start(img)
27+
28+
copy_layer(img, drawable, "layer_temp7", 700)
29+
layer_gmic = copy_layer(img, drawable, "layer_gmic", 800)
30+
layer_temp6 = copy_layer(img, drawable, "layer_temp6", 600)
31+
copy_layer(img, drawable, "layer_temp5", 500)
32+
copy_layer(img, drawable, "layer_temp4", 400)
33+
copy_layer(img, drawable, "layer_temp3", 300)
34+
35+
if shadow_intensity > 0:
36+
layer_temp2a = copy_layer(img, drawable, "layer_temp2a", 210)
37+
pdb.gimp_layer_set_mode(layer_temp2a, 3)
38+
pdb.gimp_desaturate_full(layer_temp2a, 2)
39+
pdb.gimp_threshold(layer_temp2a, shadow_intensity, 255)
40+
41+
copy_layer(img, drawable, "layer_temp1", 100)
42+
layer_temp2 = copy_layer(img, drawable, "layer_temp2", 200)
43+
pdb.gimp_levels_stretch(drawable)
44+
45+
pdb.plug_in_sel_gauss(img, layer_gmic, 4, 11)
46+
47+
pdb.gimp_layer_set_mode(layer_temp6, 3)
48+
49+
pdb.plug_in_gauss(img, layer_temp2, line_size, line_size, 1)
50+
pdb.gimp_invert(layer_temp2)
51+
pdb.gimp_layer_set_mode(layer_temp2, 16)
52+
pdb.gimp_image_merge_down(img, layer_temp2, 0)
53+
54+
layer_temp1 = pdb.gimp_image_get_active_drawable(img)
55+
pdb.gimp_threshold(layer_temp1, 245, 255)
56+
pdb.gimp_layer_set_mode(layer_temp1, 3)
57+
58+
layer_temp3 = pdb.gimp_image_get_layer_by_tattoo(img, 300)
59+
pdb.gimp_desaturate_full(layer_temp3, 2)
60+
merge_down_with_mode(img, layer_temp3, 15)
61+
62+
layer_temp5 = pdb.gimp_image_get_layer_by_tattoo(img, 500)
63+
pdb.gimp_desaturate_full(layer_temp5, 2)
64+
merge_down_with_mode(img, layer_temp5, 15)
65+
66+
layer_temp4 = pdb.gimp_image_get_layer_by_tattoo(img, 400)
67+
pdb.gimp_layer_set_mode(layer_temp4, 3)
68+
pdb.gimp_image_raise_layer(img, layer_temp4)
69+
pdb.gimp_image_merge_down(img, layer_temp4, 0)
70+
71+
layer_temp6 = pdb.gimp_image_get_layer_by_tattoo(img, 600)
72+
merge_down_with_mode(img, layer_temp6, 14)
73+
74+
layer_temp1 = pdb.gimp_image_get_layer_by_tattoo(img, 100)
75+
pdb.gimp_image_merge_down(img, layer_temp1, 0)
76+
layer_temp2a = pdb.gimp_image_get_layer_by_tattoo(img, 210)
77+
merge_down_with_mode(img, layer_temp2a, 3)
78+
layer_gmic = pdb.gimp_image_get_layer_by_tattoo(img, 800)
79+
pdb.gimp_image_merge_down(img, layer_gmic, 0)
80+
layer_temp7 = pdb.gimp_image_get_layer_by_tattoo(img, 700)
81+
pdb.gimp_levels(layer_temp7, 0, 0, 255, 1.0, 0, 255)
82+
pdb.gimp_image_merge_down(img, layer_temp7, 0)
83+
84+
pdb.gimp_image_convert_indexed(img, 0, 0, color_levels, 0, 0, "")
85+
pdb.gimp_image_convert_rgb(img)
86+
87+
pdb.gimp_displays_flush()
88+
pdb.gimp_image_undo_group_end(img)
89+
90+
91+
register(
92+
"python-fu-cartoonify-pop", # Plugin name
93+
"Pop cartoon", # Short description
94+
"Apply pop cartoon filter", # Long description
95+
"Pascal Reitermann", # Plugin author
96+
"Pascal Reitermann", # Copyright
97+
"2022", # Year of publishing
98+
"Pop...", # Name of the plug-in
99+
"*", # Supported images
100+
[
101+
(PF_IMAGE, "img", "Input image", None),
102+
(PF_DRAWABLE, "drawable", "Input drawable", None),
103+
(PF_ADJUSTMENT, "line_size", "Line thickness", 10, (2, 30, 1)),
104+
(PF_ADJUSTMENT, "shadow_intensity", "Shadow intensity", 35,
105+
(0, 50, 1)),
106+
(PF_ADJUSTMENT, "color_levels", "Color levels", 16, (4, 20, 4)),
107+
], # Input parameter
108+
[], # Output result
109+
cartoonify_pop, # Name of the function
110+
menu="<Image>/Filters/Artistic/Cartoonify"
111+
)
112+
113+
114+
def cartoonify_simple(img, drawable):
115+
"""Apply carton filter 'simple' to a given image."""
116+
pdb.gimp_image_undo_group_start(img)
117+
118+
temp_layer = pdb.gimp_layer_copy(drawable, False)
119+
pdb.gimp_image_add_layer(img, temp_layer, 0)
120+
pdb.gimp_item_set_name(temp_layer, "temp_layer")
121+
pdb.gimp_threshold(temp_layer, 127, 255)
122+
pdb.gimp_layer_set_mode(temp_layer, 14)
123+
pdb.gimp_image_merge_down(img, temp_layer, 0)
124+
pdb.gimp_image_convert_indexed(img, 0, 0, 24, 0, 0, "")
125+
pdb.gimp_image_convert_rgb(img)
126+
layer3 = pdb.gimp_image_get_active_drawable(img)
127+
pdb.gimp_posterize(layer3, 3)
128+
129+
pdb.gimp_image_undo_group_end(img)
130+
131+
132+
register(
133+
"python-fu-cartoonify-simple", # Plugin name
134+
"Simple cartoon", # Short description
135+
"Apply simple cartoon filter", # Long description
136+
"Pascal Reitermann", # Plugin author
137+
"Pascal Reitermann", # Copyright
138+
"2022", # Year of publishing
139+
"Simple...", # Name of the plug-in
140+
"*", # Supported images
141+
[
142+
(PF_IMAGE, "img", "Input image", None),
143+
(PF_DRAWABLE, "drawable", "Input drawable", None),
144+
], # Input parameter
145+
[], # Output result
146+
cartoonify_simple, # Name of the function
147+
menu="<Image>/Filters/Artistic/Cartoonify"
148+
)
149+
150+
151+
def cartoonify_realistic(img, drawable):
152+
"""Apply carton filter 'realistic' to a given image."""
153+
# docs
154+
# https://developer.gimp.org/api/2.0/libgimp/index.html
155+
# https://developer.gimp.org/api/2.0/libgimp/libgimp-gimpenums.html
156+
# https://developer.gimp.org/api/2.0/libgimp/libgimp-gimpcolor.html
157+
pdb.gimp_image_undo_group_start(img)
158+
# step 1: duplicate layer two times
159+
# layer2
160+
layer2 = pdb.gimp_layer_copy(drawable, False)
161+
pdb.gimp_image_add_layer(img, layer2, 0)
162+
pdb.gimp_item_set_name(layer2, "temp_merge_layer")
163+
164+
# layer3
165+
layer3 = pdb.gimp_layer_copy(drawable, False)
166+
pdb.gimp_image_add_layer(img, layer3, 0)
167+
pdb.gimp_item_set_name(layer3, "temp_sobel_operator")
168+
# set layer3 mode to GIMP_GRAIN_EXTRACT_MODE (20)
169+
pdb.gimp_layer_set_mode(layer3, 20)
170+
171+
# step 2: execute sobel operator
172+
# alternative pdb.plug_in_sobel(img, layer3, True, True, True)
173+
pdb.plug_in_edge(img, layer3, 1, 0, 0)
174+
175+
# step 3: adjust curves
176+
pdb.gimp_curves_spline(layer3, 0, 6,
177+
[0, 0,
178+
130, 255,
179+
255, 255])
180+
181+
# step 4: adjust levels
182+
pdb.gimp_levels(layer3, 0, 0, 130, 1.0, 0, 255)
183+
184+
# step 5: merge layers down
185+
pdb.gimp_image_merge_down(img, layer3, 0)
186+
# set layer2 mode to GIMP_OVERLAY_MODE (23)
187+
layer2 = pdb.gimp_image_get_active_drawable(img)
188+
pdb.gimp_layer_set_mode(layer2, 23)
189+
pdb.gimp_image_merge_down(img, layer2, 0)
190+
pdb.gimp_image_undo_group_end(img)
191+
192+
193+
register(
194+
"python-fu-cartoonify-realistic", # Plugin name
195+
"Realistic cartoon", # Short description
196+
"Apply realistic cartoon filter", # Long description
197+
"Pascal Reitermann", # Plugin author
198+
"Pascal Reitermann", # Copyright
199+
"2022", # Year of publishing
200+
"Realistic...", # Name of the plug-in
201+
"*", # Supported images
202+
[
203+
(PF_IMAGE, "img", "Input image", None),
204+
(PF_DRAWABLE, "drawable", "Input drawable", None),
205+
], # Input parameter
206+
[], # Output result
207+
cartoonify_realistic, # Name of the function
208+
menu="<Image>/Filters/Artistic/Cartoonify"
209+
)
210+
211+
212+
main()

0 commit comments

Comments
 (0)