simple memes piping

This commit is contained in:
klemek
2020-04-28 17:07:22 +02:00
parent 208a10c61e
commit 27b1d422a6
4 changed files with 50 additions and 32 deletions
-2
View File
@@ -11,8 +11,6 @@ if __name__ == "__main__":
meme_db.load_memes() meme_db.load_memes()
img_factory.load_fonts() img_factory.load_fonts()
# TODO better arguments reading (-h, -o, -v)
if len(sys.argv) <= 1 or utils.read_argument(sys.argv, "help", "--help", "-h"): if len(sys.argv) <= 1 or utils.read_argument(sys.argv, "help", "--help", "-h"):
print(f"Meme-Otron v{VERSION}" print(f"Meme-Otron v{VERSION}"
"python -m meme_otron -h\n" "python -m meme_otron -h\n"
+19 -2
View File
@@ -26,17 +26,34 @@ def load_fonts():
logger.error(f"Could not load font '{split[0]}'") logger.error(f"Could not load font '{split[0]}'")
def compose_image(images: List[Image.Image]) -> Image.Image:
width = min([img.size[0] for img in images])
height = sum([img.size[1] for img in images])
output_image = Image.new('RGB', (width, height))
current_height = 0
for img in images:
if img.size[0] != width:
img = img.resize((width, round(img.size[1] * width / img.size[0])), resample=Image.LANCZOS)
output_image.paste(img, (0, current_height))
current_height += img.size[1]
return output_image
def build_image(template: str, texts: List[Text], debug: bool = False) -> Optional[Image.Image]: def build_image(template: str, texts: List[Text], debug: bool = False) -> Optional[Image.Image]:
try: try:
img = Image.open(path.join(TEMPLATES_DIR, template)).convert(mode='RGBA') img = Image.open(path.join(TEMPLATES_DIR, template)).convert(mode='RGBA')
except OSError as e: except OSError as e:
logger.error(f"Could not read template file '{template}': {e}") logger.error(f"Could not read template file '{template}': {e}")
return None return None
draw = ImageDraw.Draw(img) img = apply_texts(img, texts, debug=debug)
return img
def apply_texts(img: Image.Image, texts: List[Text], debug: bool = False) -> Image.Image:
img = img.convert(mode='RGBA')
draw = ImageDraw.Draw(img)
for text in texts: for text in texts:
draw_text(draw, img, text, debug=debug) draw_text(draw, img, text, debug=debug)
return img.convert(mode='RGB') return img.convert(mode='RGB')
+28 -25
View File
@@ -1,8 +1,12 @@
import logging import logging
from typing import Optional
from PIL import Image
from .types import Text, Pos from .types import Text, Pos
from . import img_factory as imgf from . import img_factory
from . import meme_db as db from . import meme_db
from . import utils
logger = logging.getLogger("meme_otron") logger = logging.getLogger("meme_otron")
@@ -21,26 +25,29 @@ left_wmark.x_range = [0.005, 0.995]
left_wmark.y_range = [0.005, 0.995] left_wmark.y_range = [0.005, 0.995]
def parse_text(s): def compute(*args: str, left_wmark_text: Optional[Text] = None, debug: bool = False) -> Optional[Image.Image]:
"""
:param (str) s:
:rtype: str
"""
return s.replace("\\n", "\n")
def compute(*args, left_wmark_text=None, debug=False):
"""
:param (str) left_wmark_text:
:param (bool) debug:
:param (str) args:
:rtype: PIL.Image.Image
:return:
"""
if len(args) < 1: if len(args) < 1:
return None return None
parts = utils.split_arguments(args, "-")
images = []
for part in parts:
images += [compute_part(*part, debug=debug)]
output_image = img_factory.compose_image(images)
watermarks = [right_wmark]
if left_wmark_text is not None:
left_wmark.text = left_wmark_text
watermarks += [left_wmark]
output_image = img_factory.apply_texts(output_image, watermarks, debug=debug)
return output_image
def compute_part(*args: str, debug: bool = False) -> Optional[Image.Image]:
meme_id = args[0] meme_id = args[0]
meme = db.get_meme(meme_id) meme = meme_db.get_meme(meme_id)
if meme is None: if meme is None:
logger.warning(f"Meme template '{meme_id}' not found") logger.warning(f"Meme template '{meme_id}' not found")
return None return None
@@ -49,14 +56,10 @@ def compute(*args, left_wmark_text=None, debug=False):
for i in range(len(meme.texts)): for i in range(len(meme.texts)):
if meme.texts[i].text_ref is None: if meme.texts[i].text_ref is None:
if c < len(args) - 1: if c < len(args) - 1:
meme.texts[i].text = parse_text(args[c + 1]) meme.texts[i].text = args[c + 1].replace("\\n", "\n")
else: else:
meme.texts[i].text = "" meme.texts[i].text = ""
c += 1 c += 1
else: else:
meme.texts[i].text = meme.texts[meme.texts[i].text_ref].text meme.texts[i].text = meme.texts[meme.texts[i].text_ref].text
meme.texts += [right_wmark] return img_factory.build_image(meme.template, meme.texts, debug=debug)
if left_wmark_text is not None:
left_wmark.text = left_wmark_text
meme.texts += [left_wmark]
return imgf.build_image(meme.template, meme.texts, debug=debug)
+3 -3
View File
@@ -1,7 +1,7 @@
import re import re
import sys import sys
import os.path as path import os.path as path
from typing import List, Optional, Union from typing import List, Optional, Union, Tuple
from Levenshtein import distance from Levenshtein import distance
@@ -114,14 +114,14 @@ def read_argument(args: List[str], *names: str, valued: bool = False, delete: bo
return None return None
def split_arguments(args: List[str], separator: str) -> List[List[str]]: def split_arguments(args: Union[List[str], Tuple[str]], separator: str) -> List[List[str]]:
output = [[]] output = [[]]
for argument in args: for argument in args:
if argument == separator: if argument == separator:
output += [[]] output += [[]]
else: else:
output[-1] += [argument] output[-1] += [argument]
return [block for block in output if len(block) > 0] return [part for part in output if len(part) > 0]
# endregion # endregion