Skip to content

Commit ddc9861

Browse files
authored
Merge pull request #20 from pablodiegoss/add-white-border
Add white border parameters
2 parents dbb884c + eda3b3c commit ddc9861

21 files changed

+678
-202
lines changed

.github/workflows/python-app.yml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,15 @@ jobs:
1616

1717
steps:
1818
- uses: actions/checkout@v2
19-
- name: Set up Python 3.7
19+
- name: Set up Python 3.12
2020
uses: actions/setup-python@v2
2121
with:
22-
python-version: 3.7
22+
python-version: 3.12
2323
- name: Install dependencies
2424
run: |
2525
python -m pip install --upgrade pip
26-
pip install black
27-
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28-
- name: Lint with black
26+
pip install poetry==1.8.4
27+
poetry install
28+
- name: Test with pytest
2929
run: |
30-
black . --check
31-
- name: Test with unittest
32-
run: |
33-
python -m unittest -v tests/*.py
30+
poetry run pytest -v

.github/workflows/python-publish.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ jobs:
1717
- name: Set up Python
1818
uses: actions/setup-python@v2
1919
with:
20-
python-version: '3.x'
20+
python-version: '3.12'
2121
- name: Install dependencies
2222
run: |
2323
python -m pip install --upgrade pip
24-
pip install poetry
24+
pip install poetry==1.8.4
2525
- name: Set Release Version
2626
id: vars
2727
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
@@ -30,5 +30,5 @@ jobs:
3030
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
3131
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
3232
run: |
33-
sed -i 's/PLACE_HOLDER_VERSION/${{ env.RELEASE_VERSION }}/' pyproject.toml
33+
sed -i 's/0.0.0/${{ env.RELEASE_VERSION }}/' pyproject.toml
3434
poetry publish --build

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
lint:
3+
ruff format pymarker
4+
ruff check --extend-select I --fix pymarker
5+
6+
check:
7+
ruff check

poetry.lock

Lines changed: 325 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pymarker/__init__.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1-
from .core import *
2-
from .cli import *
3-
from .utils import *
1+
from .cli import generate_patt_and_marker as generate_patt_and_marker
2+
from .core import (
3+
generate_marker as generate_marker,
4+
)
5+
from .core import (
6+
generate_marker_from_image as generate_marker_from_image,
7+
)
8+
from .core import (
9+
generate_patt as generate_patt,
10+
)
11+
from .core import (
12+
generate_patt_from_image as generate_patt_from_image,
13+
)

pymarker/cli.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
11
import click
2+
23
from .core import generate_marker, generate_patt
4+
from .exceptions import BlackBorderSizeError, WhiteBorderSizeError
35
from .utils import echo
46

57

68
@click.command()
79
@click.argument("filename")
810
@click.option("--patt", "-p", is_flag=True, default=False)
911
@click.option("--marker", "-m", is_flag=True, default=False)
10-
@click.option("--string", "-s", is_flag=True, default=False)
11-
@click.option("--border-size", "-b", default=50) # 50% is based on template hiro marker
12+
@click.option("--as_string", "-s", is_flag=True, default=False)
13+
@click.option("--black-border-size", "-b", default=20)
14+
@click.option("--white-border-size", "-w", default=3)
1215
@click.option("--output", "-o", default=None, type=str)
13-
def generate_patt_and_marker(filename, patt, marker, string, border_size, output):
14-
echo("-- Starting PyMarker Generator --".format(filename), silent=string)
15-
if (patt and marker) or (not patt and not marker):
16-
echo("Generating patt and marker for {}".format(filename), silent=string)
17-
# generate_patt must be silent if you are not using the flag string.
18-
echo(generate_patt(filename, output, string), silent=not string)
19-
generate_marker(filename, border_size, output)
20-
elif marker:
21-
echo("Generating marker for {}".format(filename), silent=string)
22-
generate_marker(filename, border_size, output)
23-
elif patt:
24-
echo("Generating patt for {}".format(filename), silent=string)
25-
echo(generate_patt(filename, output, string), silent=not string)
26-
27-
echo("Done.", silent=string)
16+
def generate_patt_and_marker(
17+
filename, patt, marker, as_string, black_border_size, white_border_size, output
18+
):
19+
echo("-- Starting PyMarker Generator --".format(), silent=as_string)
20+
if marker or (not patt and not marker):
21+
echo("Generating marker for {}".format(filename), silent=as_string)
22+
try:
23+
generate_marker(filename, black_border_size, output, white_border_size)
24+
except BlackBorderSizeError:
25+
echo("Black border size cannot be less or equal 0 or bigger than 50%")
26+
return
27+
except WhiteBorderSizeError:
28+
echo("White border size cannot be less than 0 or bigger than 50%")
29+
return
30+
31+
if patt or (not patt and not marker):
32+
echo("Generating patt for {}".format(filename), silent=as_string)
33+
echo(generate_patt(filename, output, as_string), silent=not as_string)
34+
35+
echo("Done.", silent=as_string)
2836

2937

3038
def main():

pymarker/core.py

Lines changed: 56 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
1+
from PIL import Image
2+
3+
from .exceptions import BlackBorderSizeError, WhiteBorderSizeError
14
from .utils import (
2-
open_image,
3-
get_box_coords,
4-
remove_extension,
5+
PattStr,
6+
add_border,
7+
calculate_border,
8+
check_path,
9+
color_to_file,
10+
create_and_open_patt,
11+
generate_white_background,
512
get_dir,
613
get_name,
7-
check_path,
8-
PattStr,
14+
open_image,
915
square_image,
1016
)
11-
from PIL import Image
12-
from math import ceil
13-
14-
15-
def get_marker_size(image, border_size):
16-
size = image.height + (border_size * 2)
17-
# Using the size double because the resulting marker should be a square.
18-
return (size, size)
19-
20-
21-
def create_empty_patt(filename):
22-
patt_name = remove_extension(filename) + ".patt"
23-
patt_file = open(patt_name, "w")
24-
patt_file.close()
25-
return patt_name
26-
2717

28-
def create_and_open_patt(filename):
29-
patt_name = create_empty_patt(filename)
30-
return open(patt_name, "a")
18+
DEFAULT_BLACK_BORDER_PERCENTAGE = 20
19+
DEFAULT_WHITE_BORDER_PERCENTAGE = 3
3120

3221

33-
def generate_patt(filename, output=None, string=False):
22+
def generate_patt(filename: str, output: str = None, string: bool = False):
3423
if filename:
3524
image = open_image(filename)
3625
# Patt default marker size is 16x16 pixels
@@ -56,8 +45,7 @@ def generate_patt(filename, output=None, string=False):
5645
raise FileNotFoundError
5746

5847

59-
def generate_patt_from_image(image):
60-
48+
def generate_patt_from_image(image: Image.Image) -> PattStr:
6149
# Patt default marker size is 16x16 pixels
6250
image = image.resize((16, 16))
6351

@@ -76,60 +64,56 @@ def generate_patt_from_image(image):
7664
return patt.close()
7765

7866

79-
def generate_marker_from_image(image: Image.Image, border_percentage=50):
80-
81-
image = square_image(image)
82-
border_size = ceil(image.height * (border_percentage / 100))
83-
84-
new_image = generate_white_background(image)
85-
86-
# Default color is black, setting (0, 0, 0) for clarity, as the border should be black
87-
marker_size = get_marker_size(new_image, border_size)
88-
marker = Image.new("RGB", marker_size, (0, 0, 0))
89-
marker.paste(new_image, get_box_coords(new_image, border_size))
67+
def generate_marker_from_image(
68+
original_image: Image.Image,
69+
black_border_percentage=DEFAULT_BLACK_BORDER_PERCENTAGE,
70+
white_border_percentage=DEFAULT_WHITE_BORDER_PERCENTAGE,
71+
) -> Image.Image:
72+
squared_image = square_image(original_image)
73+
try:
74+
black_border_size = calculate_border(
75+
squared_image.height, (black_border_percentage / 100)
76+
)
77+
except ValueError as e:
78+
raise BlackBorderSizeError(str(e))
79+
80+
# Create a white background if the image has transparency
81+
marker_middle_image = generate_white_background(squared_image)
82+
83+
# Add black border
84+
black = (0, 0, 0)
85+
marker = add_border(marker_middle_image, black_border_size, black)
86+
87+
if white_border_percentage != 0:
88+
try:
89+
white_border_size = calculate_border(
90+
squared_image.height, (white_border_percentage / 100)
91+
)
92+
except ValueError as e:
93+
raise WhiteBorderSizeError(str(e))
94+
95+
# Add white border
96+
white = (255, 255, 255)
97+
marker = add_border(marker, white_border_size, white)
9098

9199
return marker
92100

93101

94-
def patt_number_format(point):
95-
return str(point).rjust(3, " ")
96-
97-
98-
# Prints all pixels from a split color to the patt file
99-
def color_to_file(c, patt):
100-
n = 1
101-
for point in list(c.getdata()):
102-
patt.write(patt_number_format(point))
103-
if n != 0 and n % 16 == 0:
104-
n = 0
105-
patt.write("\n")
106-
else:
107-
patt.write(" ")
108-
n += 1
109-
110-
111-
def generate_white_background(image):
112-
if len(image.split()) > 3:
113-
white_image = Image.new("RGB", image.size, (255, 255, 255))
114-
white_image.paste(image, mask=image.split()[3])
115-
return white_image
116-
return image
117-
118-
119-
def generate_marker(filename, border_percentage=50, output=None):
102+
def generate_marker(
103+
filename: str,
104+
black_border_percentage: int = DEFAULT_BLACK_BORDER_PERCENTAGE,
105+
output=None,
106+
white_border_percentage: int = DEFAULT_WHITE_BORDER_PERCENTAGE,
107+
):
120108
if filename:
121109
image = open_image(filename)
122110
output = check_path(output) if output else get_dir(filename)
123111
name = get_name(filename)
124112

125-
border_size = ceil(image.height * (border_percentage / 100))
126-
127-
new_image = generate_white_background(image)
113+
border_marker = generate_marker_from_image(
114+
image, black_border_percentage, white_border_percentage
115+
)
128116

129-
# Default color is black, setting (0, 0, 0) for clarity, as the border should be black
130-
marker_size = get_marker_size(new_image, border_size)
131-
marker = Image.new("RGB", marker_size, (0, 0, 0))
132-
marker.paste(new_image, get_box_coords(new_image, border_size))
133-
marker.save(output + name + "_marker.png", "PNG")
117+
border_marker.save(output + name + "_marker.png", "PNG")
134118
else:
135119
raise FileNotFoundError

pymarker/exceptions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class BlackBorderSizeError(Exception):
2+
"""Exception raised for errors in the black border size."""
3+
4+
def __init__(self, message="Black border size must be between 1% and 49%."):
5+
self.message = message
6+
super().__init__(self.message)
7+
8+
9+
class WhiteBorderSizeError(Exception):
10+
"""Exception raised for errors in the white border size."""
11+
12+
def __init__(self, message="White border size must be between 1% and 49%."):
13+
self.message = message
14+
super().__init__(self.message)

0 commit comments

Comments
 (0)