rotated text
This commit is contained in:
+35
-16
@@ -38,24 +38,24 @@ def make(template, texts, debug=False):
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
img = Image.open(path.join(TEMPLATES_DIR, template))
|
||||
img = Image.open(path.join(TEMPLATES_DIR, template)).convert(mode='RGBA')
|
||||
except OSError as e:
|
||||
logger.error(f"Could not read template file '{template}': {e}")
|
||||
return None
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
for text in texts:
|
||||
draw_text(draw, img.size, text, debug=debug)
|
||||
draw_text(draw, img, text, debug=debug)
|
||||
|
||||
return img
|
||||
return img.convert(mode='RGB')
|
||||
|
||||
|
||||
def draw_text(draw, size, text, debug=False):
|
||||
def draw_text(draw, img, text, debug=False):
|
||||
"""
|
||||
TODO
|
||||
|
||||
:param (PIL.ImageDraw.ImageDraw) draw: source image canvas
|
||||
:param (int,int) size: source image size
|
||||
:param (PIL.Image.Image) img: source image
|
||||
:param (Text) text:
|
||||
:param (bool) debug:
|
||||
"""
|
||||
@@ -64,14 +64,31 @@ def draw_text(draw, size, text, debug=False):
|
||||
if text.text is not None and len(text.text.strip()) > 0:
|
||||
text.init() # load default values
|
||||
if text.font in FONTS:
|
||||
text.text, font = fit_text(size, text)
|
||||
draw.text(get_pos(size, text, font), text.text, fill=text.fill, align=text.align, font=font,
|
||||
stroke_width=round(text.stroke_width * font.size), stroke_fill=text.stroke_fill)
|
||||
if debug:
|
||||
draw.rectangle([(text.x_range[0] * size[0], text.y_range[0] * size[1]),
|
||||
(text.x_range[1] * size[0], text.y_range[1] * size[1])],
|
||||
None,
|
||||
(128, 128, 128))
|
||||
text.text, font = fit_text(img.size, text)
|
||||
if text.angle == 0:
|
||||
draw.text(get_pos(img.size, text, font), text.text, fill=text.fill, align=text.align, font=font,
|
||||
stroke_width=round(text.stroke_width * font.size), stroke_fill=text.stroke_fill)
|
||||
if debug:
|
||||
draw.rectangle([(text.x_range[0] * img.size[0], text.y_range[0] * img.size[1]),
|
||||
(text.x_range[1] * img.size[0], text.y_range[1] * img.size[1])],
|
||||
None, (128, 128, 128))
|
||||
else:
|
||||
width = round((text.x_range[1] - text.x_range[0]) * img.size[0])
|
||||
height = round((text.y_range[1] - text.y_range[0]) * img.size[1])
|
||||
center_x = (text.x_range[0] + text.x_range[1]) * img.size[0] / 2
|
||||
center_y = (text.y_range[0] + text.y_range[1]) * img.size[1] / 2
|
||||
txt_img = Image.new('RGBA', (width, height))
|
||||
txt_draw = ImageDraw.Draw(txt_img)
|
||||
txt_draw.text(get_pos(img.size, text, font, relative=True), text.text, fill=text.fill,
|
||||
align=text.align, font=font, stroke_width=round(text.stroke_width * font.size),
|
||||
stroke_fill=text.stroke_fill)
|
||||
if debug:
|
||||
txt_draw.rectangle([(0, 0), (width - 1, height - 1)],
|
||||
None, (128, 128, 128))
|
||||
txt_img = txt_img.rotate(text.angle, expand=1, resample=Image.BILINEAR)
|
||||
img.paste(txt_img,
|
||||
(round(center_x - txt_img.size[0] / 2), round(center_y - txt_img.size[1] / 2)),
|
||||
txt_img)
|
||||
else:
|
||||
logger.warning(f"Invalid font '{text.font}'")
|
||||
|
||||
@@ -107,7 +124,7 @@ def fit_text(size, text):
|
||||
return t, font
|
||||
|
||||
|
||||
def get_pos(size, text, font):
|
||||
def get_pos(size, text, font, relative=False):
|
||||
"""
|
||||
TODO
|
||||
|
||||
@@ -136,5 +153,7 @@ def get_pos(size, text, font):
|
||||
pos_x = round((min_x + max_x) / 2 - text_size[0] / 2)
|
||||
else:
|
||||
pos_x = max_x - text_size[0]
|
||||
|
||||
return pos_x, pos_y
|
||||
if relative:
|
||||
return pos_x - min_x, pos_y - min_y
|
||||
else:
|
||||
return pos_x, pos_y
|
||||
|
||||
@@ -105,9 +105,10 @@ def load_text(j, raw_text, text=None):
|
||||
text.font = utils.read_key_safe(raw_text, "font", types=[str])
|
||||
text.x_range = utils.read_key_safe(raw_text, "x_range", types=[float, int], is_list=True, is_list_size=2)
|
||||
text.y_range = utils.read_key_safe(raw_text, "y_range", types=[float, int], is_list=True, is_list_size=2)
|
||||
text.font_size = utils.read_key_safe(raw_text, "font_size", types=[float])
|
||||
text.angle = utils.read_key_safe(raw_text, "angle", types=[float, int])
|
||||
text.font_size = utils.read_key_safe(raw_text, "font_size", types=[float, int])
|
||||
text.fill = utils.read_key_safe(raw_text, "fill", types=[int], is_list=True, is_list_size=3)
|
||||
text.stroke_width = utils.read_key_safe(raw_text, "stroke_width", types=[float])
|
||||
text.stroke_width = utils.read_key_safe(raw_text, "stroke_width", types=[float, int])
|
||||
text.stroke_fill = utils.read_key_safe(raw_text, "stroke_fill", types=[int], is_list=True, is_list_size=3)
|
||||
if "position" in raw_text:
|
||||
if raw_text["position"] not in [p.name for p in Pos]:
|
||||
|
||||
@@ -58,6 +58,7 @@ class Text:
|
||||
|
||||
self.x_range = (0, 1)
|
||||
self.y_range = (0, 1)
|
||||
self.angle = None
|
||||
|
||||
self.font = None
|
||||
self.font_size = None
|
||||
@@ -83,6 +84,12 @@ class Text:
|
||||
"""
|
||||
TODO
|
||||
"""
|
||||
if self.x_range is None:
|
||||
self.x_range = (0, 1)
|
||||
if self.y_range is None:
|
||||
self.y_range = (0, 1)
|
||||
if self.angle is None:
|
||||
self.angle = 0
|
||||
if self.font is None:
|
||||
self.font = DEFAULT_FONT
|
||||
if self.font_size is None:
|
||||
|
||||
+66
-11
@@ -286,14 +286,69 @@
|
||||
"aliases": ["tom", "jerry"],
|
||||
"font": "impact",
|
||||
"font_size": 0.07,
|
||||
"stroke_fill": [255, 255, 255],
|
||||
"stroke_width": 0.1,
|
||||
"texts": [{
|
||||
"x_range": [0.07, 0.36],
|
||||
"y_range": [0.69, 0.98],
|
||||
"font_size": 0.05
|
||||
},{
|
||||
"x_range": [0.44, 0.84],
|
||||
"y_range": [0.27, 0.59]
|
||||
}]
|
||||
}]
|
||||
"stroke_fill": [
|
||||
255,
|
||||
255,
|
||||
255
|
||||
],
|
||||
"stroke_width": 0.1,
|
||||
"texts": [
|
||||
{
|
||||
"x_range": [
|
||||
0.07,
|
||||
0.36
|
||||
],
|
||||
"y_range": [
|
||||
0.69,
|
||||
0.98
|
||||
],
|
||||
"font_size": 0.05
|
||||
},
|
||||
{
|
||||
"x_range": [
|
||||
0.44,
|
||||
0.84
|
||||
],
|
||||
"y_range": [
|
||||
0.27,
|
||||
0.59
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "button",
|
||||
"template": "button.jpg",
|
||||
"stroke_fill": [
|
||||
255,
|
||||
255,
|
||||
255
|
||||
],
|
||||
"stroke_width": 0.1,
|
||||
"font_size": 0.08,
|
||||
"texts": [
|
||||
{
|
||||
"x_range": [
|
||||
0.10,
|
||||
0.46
|
||||
],
|
||||
"y_range": [
|
||||
0.46,
|
||||
0.80
|
||||
],
|
||||
"angle": 2
|
||||
},
|
||||
{
|
||||
"x_range": [
|
||||
0.48,
|
||||
0.88
|
||||
],
|
||||
"y_range": [
|
||||
0.28,
|
||||
0.68
|
||||
],
|
||||
"angle": -45
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user