Skip to content

Commit

Permalink
v 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ZyMa-1 committed Aug 6, 2023
1 parent f222e9d commit 6ef42dc
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 94 deletions.
4 changes: 2 additions & 2 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Add possibility of inputting HEX in color parameters
Add text-outline-font-family, text-outline-font-color, bg-blur variables
Add possibility of inputting HEX in color parameters [done]
Add text-outline-thickness, text-outline-color, bg-blur variables [done]
50 changes: 31 additions & 19 deletions data/styles/default-style.yaml
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
####################
#
# border-thickness: {int number}px | Thickness in pixels
# border-thickness: {float number}% | Border thickness in pixels relative to min(width, height)
# border-thickness: {int number}px | Thickness in pixels
# border-thickness: {float number}% | Border thickness in pixels relative to min(width, height)
#
# border-color: {string} | Name of the color: "black", "white", etc.
# border-color: {0-255},{0-255},{0-255} | RGB color
# border-color: {string} | Name of the color: "black", "white", etc.
# border-color: {HEX string} | Hex string of the color. For example #4287f5, #ffffff, etc.
# border-color: {0-255},{0-255},{0-255} | RGB color
#
# font-size: {int number}px | Font size in pixels
# font-size: {float number}% | Font size in pixels relative to min(width, height)
# font-size: {int number}px | Font size in pixels
# font-size: {float number}% | Font size in pixels relative to min(width, height)
#
# crop-vertical-size: {int number}px | Crop image from the top and the bottom by a given amount of pixels
# crop-vertical-size: {float number}% | Crop image from the top and the bottom by a given amount of pixels
# | relative to min(width, height)
# bg-crop-vertical-size: {int number}px | Crop image from the top and the bottom by a given amount of pixels
# bg-crop-vertical-size: {float number}% | Crop image from the top and the bottom by a given amount of pixels
# | relative to min(width, height)
#
# font-color: {string} | Name of the color: "black", "white", etc.
# font-color: {0-255},{0-255},{0-255} | RGB color
# font-color: {string} | Name of the color: "black", "white", etc.
# font-color: {HEX string} | Hex string of the color. For example #4287f5, #ffffff, etc.
# font-color: {0-255},{0-255},{0-255} | RGB color
#
# font-family: {string} | Path to the 'ttf' font file
# font-family: default | 'data/fonts/SourceCodePro-Regular.ttf'
# font-family: {string} | Path to the 'ttf' font file
# font-family: default | 'data/fonts/SourceCodePro-Regular.ttf'
#
# text: YAML list of python f-strings |
# text: default | ["{artist} - {title}", "Beatmap by {creator}"]
# text: YAML list of python f-strings |
# text: default | ["{artist} - {title}", "Beatmap by {creator}"]
#
# Available f-strings: ('title', 'title_unicode', 'artist', 'artist_unicode',
# 'creator', 'source', 'beatmap_id', 'beatmap_set_id')
# I.e. Some metadata
#
# I.e. Some metadata
#
# text-outline-thickness: {int}px | Thickness radius, recommended to specify it in px
#
# text-outline-color: {string} | Name of the color: "black", "white", etc.
# text-outline-color: {HEX string} | Hex string of the color. For example #4287f5, #ffffff, etc.
# text-outline-color: {0-255},{0-255},{0-255} | RGB color
#
# bg-blur-radius: {int}px | Gaussian blur specified in px
#
###################
$schema: ../yaml_schemas/yaml_schema.json # Just specifying a schema, not necessary
parameters:
border-thickness: 5%
border-color: white
font-size: 60px
crop-vertical-size: 15%
bg-crop-vertical-size: 15%
font-color: white
font-family: default
text: default
text: default
text-outline-thickness: 2px
text-outline-color: black
bg-blur-radius: 10px
13 changes: 8 additions & 5 deletions data/styles/masyunya_style.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
parameters:
border-thickness: 5%
border-color: 255,10,210
font-size: 60px
crop-vertical-size: 20%
border-color: black
font-size: 70px
bg-crop-vertical-size: 20%
font-color: black
font-family: data/fonts/ofont.ru_Oldtimer.ttf
text: default
font-family: default
text: default
text-outline-thickness: 4px
text-outline-color: white
bg-blur-radius: 2px
2 changes: 1 addition & 1 deletion data/styles/style1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ parameters:
border-thickness: 5%
border-color: black
font-size: 60px
crop-vertical-size: 20%
bg-crop-vertical-size: 20%
font-color: white
font-family: default
text: default
44 changes: 0 additions & 44 deletions data/yaml_schemas/yaml_schema.json

This file was deleted.

15 changes: 11 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,27 @@ def exec_main_parameters(*, args, parameters, save_image=True):
border_thickness = ArgumentParser.parse_size_value(parameters['border-thickness'])
border_color = ArgumentParser.parse_color_value(parameters['border-color'])
font_size = ArgumentParser.parse_size_value(parameters['font-size'])
crop_vertical_size = ArgumentParser.parse_size_value(parameters['crop-vertical-size'])
bg_crop_vertical_size = ArgumentParser.parse_size_value(parameters['bg-crop-vertical-size'])
font_color = ArgumentParser.parse_color_value(parameters['font-color'])
font_family = ArgumentParser.parse_font_family_value(parameters['font-family'])
text_outline_thickness = ArgumentParser.parse_px_value(parameters['text-outline-thickness'])
text_outline_color = ArgumentParser.parse_color_value(parameters['text-outline-color'])
text = ArgumentParser.parse_text_value(parameters['text'])
bg_blur_radius = ArgumentParser.parse_px_value(parameters['bg-blur-radius'])

input_file = args.input_file
output_file_path = args.output

beatmap_banner_drawer = BeatmapBannerDrawer(input_file)
beatmap_banner_drawer.crop_image(crop_vertical_size=crop_vertical_size)
beatmap_banner_drawer.crop_image(crop_vertical_size=bg_crop_vertical_size)
beatmap_banner_drawer.blur_image(radius=bg_blur_radius)
beatmap_banner_drawer.draw_border(thickness=border_thickness, color=border_color)
beatmap_banner_drawer.draw_text_centered(text, font_size=font_size,
beatmap_banner_drawer.draw_text_centered(text,
font_size=font_size,
font_color=font_color,
font_family=font_family)
font_family=font_family,
outline_thickness=text_outline_thickness,
outline_color=text_outline_color)

if save_image:
beatmap_banner_drawer.save_image(output_file_path)
Expand Down
29 changes: 28 additions & 1 deletion src/ArgumentParser.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import pathlib

from PIL import ImageColor

from src.PathManager import PathManager


class ArgumentParser:
@staticmethod
def parse_px_value(arg: str) -> int:
if arg[-2:] == 'px':
val = int(arg[:-2])
if val >= 0:
return val
else:
raise ValueError("Bad argument.")
else:
raise ValueError("Bad argument.")

@staticmethod
def parse_size_value(arg: str) -> int | float:
if arg[-1] == '%':
Expand Down Expand Up @@ -32,8 +45,22 @@ def parse_color_value(arg: str) -> tuple | str:
if not all(0 <= int(arg) <= 255 for arg in args):
raise ValueError("Bad argument.")
return tuple(args)
else:
elif isinstance(arg, str) and arg[0] == '#' and len(arg) == 7:
arg = arg[1:]
r = int(arg[0:2], 16)
g = int(arg[2:4], 16)
b = int(arg[4:6], 16)
if not all(0 <= int(arg) <= 255 for arg in [r, g, b]):
raise ValueError("Bad argument.")
return r, g, b
elif isinstance(arg, str):
try:
arg = ImageColor.getrgb(arg)
except ValueError:
raise ValueError(f"Invalid color name: {arg}")
return arg
else:
raise ValueError("Bad argument.")

@staticmethod
def parse_font_family_value(arg: str) -> pathlib.Path:
Expand Down
19 changes: 6 additions & 13 deletions src/BeatmapBannerDrawer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pathlib

from OsuFileParser import BeatmapFileParser, BeatmapData
from PIL import Image, ImageDraw, ImageFont, ImageColor
from PIL import Image, ImageDraw, ImageFont, ImageFilter

from src.TextParser import TextParser

Expand All @@ -28,11 +28,6 @@ def draw_border(self, *, thickness, color):
if isinstance(thickness, float):
thickness = int(min(image_width, image_height) * thickness)

if isinstance(color, str):
try:
color = ImageColor.getrgb(color)
except ValueError:
raise ValueError(f"Invalid color name: {color}")
##############################

for i in range(thickness):
Expand All @@ -47,7 +42,7 @@ def draw_border(self, *, thickness, color):
except ValueError: # Check for bad coordinates
pass

def draw_text_centered(self, text, *, font_family, font_size, font_color):
def draw_text_centered(self, text, *, font_family, font_size, font_color, outline_color, outline_thickness):
if font_size == 0:
return

Expand All @@ -60,11 +55,6 @@ def draw_text_centered(self, text, *, font_family, font_size, font_color):

text = TextParser.parse_text(text, beatmap_data=self.beatmap_data)

if isinstance(font_color, str):
try:
font_color = ImageColor.getrgb(font_color)
except ValueError:
raise ValueError(f"Invalid color name: {font_color}")
###########################

font = ImageFont.truetype(str(font_family), font_size)
Expand All @@ -78,7 +68,7 @@ def draw_text_centered(self, text, *, font_family, font_size, font_color):
offset_y = center_y - bbox_center_y
try:
draw.multiline_text((bbox[0] + offset_x, bbox[1] + offset_y), text, font=font, fill=font_color,
align="center")
align="center", stroke_width=outline_thickness, stroke_fill=outline_color)
except ValueError: # Check for bad coordinates
pass

Expand All @@ -103,6 +93,9 @@ def crop_image(self, *, crop_vertical_size):
except ValueError: # Check for bad coordinates
pass

def blur_image(self, *, radius):
self.image = self.image.filter(ImageFilter.GaussianBlur(radius))

def save_image(self, output_path):
self.image.save(output_path)

Expand Down
15 changes: 12 additions & 3 deletions tests/StyleValuesGenerator.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
class StyleValuesGenerator:
@staticmethod
def generate_px_valid_values():
return ["0px", "10px", "50px", "1000px"]

@staticmethod
def generate_px_bad_values():
return ["-1px", "-2px", "-2.0px"]

@staticmethod
def generate_size_valid_values():
return ["0%", "10%", "50.5%", "99%", "100%", "0px", "10px", "50px", "1000px"]

@staticmethod
def generate_size_bad_values():
return ["-1%", "101%", "-1px"]
return ["-1%", "101%", "-1px", "-2px", "-2.0px"]

@staticmethod
def generate_color_valid_values():
return ['white', 'black', 'red', 'blue', "0,0,0", "255,255,255", "255,0,0", "255, 125, 125"]
return ['white', 'black', 'red', 'blue', "0,0,0", "255,255,255", "255,0,0", "255, 125, 125",
"#a4eb34", "#ffffff", "#000000"]

@staticmethod
def generate_color_bad_values():
return ["color_name_that_does_not_exists", "-1,0,0"]
return ["color_name_that_does_not_exists", "-1,0,0", "#gggggg", "#-1-1-1-1", "#0123gf", "#0000000"]

@staticmethod
def generate_font_family_valid_values():
Expand Down
7 changes: 5 additions & 2 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ def test_main_valid(self):
'border-thickness': SVGen.generate_size_valid_values(),
'border-color': SVGen.generate_color_valid_values(),
'font-size': SVGen.generate_size_valid_values(),
'crop-vertical-size': SVGen.generate_size_valid_values(),
'bg-crop-vertical-size': SVGen.generate_size_valid_values(),
'font-color': SVGen.generate_color_valid_values(),
'font-family': SVGen.generate_font_family_valid_values(),
'text': SVGen.generate_text_valid_values()
'text': SVGen.generate_text_valid_values(),
'text-outline-thickness': SVGen.generate_px_valid_values(),
'text-outline-color': SVGen.generate_color_valid_values(),
'bg-blur-radius': SVGen.generate_px_valid_values()
}

for args, parameters in generate_args_and_parameters(pre_data):
Expand Down

0 comments on commit 6ef42dc

Please sign in to comment.