Update Meme Generator project

This commit is contained in:
2026-01-04 14:03:10 -08:00
parent 155f0c9c6d
commit 433f2ba034
9 changed files with 66 additions and 28 deletions

View File

@@ -11,6 +11,23 @@ class MemeEngine:
"""Initialize meme engine with path to save generated memes."""
self.output_path = output_path
def resize_image(self, img, width=500):
"""Resize image to specified width while maintaining aspect ratio."""
if img.size[0] > width:
ratio = width / (img.size[0] * 1.0)
height = ratio * img.size[1]
img = img.resize((int(width), int(height)), Image.NEAREST)
return img
def draw_text(self, image, message):
"""Draw text on the image."""
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(
"./_data/font/calibri_regular.ttf", int(image.size[1] / 20)
)
draw.text((20, 20), message, font=font, fill="white")
return image
def make_meme(self, img_path, text, author, width=500) -> str:
"""Generate a meme image with given text and author."""
output_file = f"{self.output_path}/{random.randint(0, 10000)}.jpg"
@@ -18,17 +35,9 @@ class MemeEngine:
try:
with Image.open(img_path) as img:
# Resize image while maintaining aspect ratio
width = 500 if img.size[0] > 500 else img.size[0]
ratio = width / (img.size[0] * 1.0)
height = ratio * img.size[1]
img = img.resize((int(width), int(height)), Image.NEAREST)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(
"./_data/font/calibri_regular.ttf", int(height / 20)
)
draw.text((20, 20), message, font=font, fill="white")
img.save(output_file)
image_resize = self.resize_image(img, width=width)
image_draw = self.draw_text(image_resize, message)
image_draw.save(output_file)
except Exception as err:
print(f"Error: {err}")

View File

@@ -1 +1,6 @@
"""MemeEngine package.
Provides the MemeEngine class for generating meme images from templates.
"""
from .MemeEngine import MemeEngine

View File

@@ -19,5 +19,6 @@ class IngestorInterface(ABC):
@classmethod
@abstractmethod
def parse(cls, path: str) -> List[QuoteModel]:
"""Abstract method to parse the file and return a list of QuoteModel objects."""
"""Abstract method to parse the file and return a list of QuoteModel
objects."""
pass

View File

@@ -23,7 +23,7 @@ class PDFIngestor(IngestorInterface):
tmp = f"./tmp/{random.randint(0, 10000)}.txt"
try:
# pdftotext <input-pdf> <output-text-file>
call = subprocess.call(["pdftotext", path, tmp])
subprocess.call(["pdftotext", path, tmp])
with open(tmp, "r") as file:
lines = file.readlines()
except FileNotFoundError as err:

View File

@@ -10,5 +10,5 @@ class QuoteModel:
self.author = author
def __repr__(self):
"""String representation of the QuoteModel object."""
"""Return a string representation of the QuoteModel."""
return f"{self.body} - {self.author}"

View File

@@ -1,3 +1,8 @@
"""QuoteEngine package.
Provides tools for parsing and representing quote data.
"""
from .IngestorInterface import IngestorInterface
from .CSVIngestor import CSVIngestor
from .DocxIngestor import DocxIngestor

View File

@@ -37,3 +37,16 @@ Open link `http://127.0.0.1:5000` in web browser
`DocxIngestor`: Module for ingesting Docx files containing quotes. \
`TextIngestor`: Module for ingesting text files containing quotes. \
`PDFIngestor`: Module for ingesting PDF files containing quotes.
### Format checking
```sh
$ pip install docformatter
$ pip install autopep8
$ pip install black
$ pip install flake8
$ docformatter -i -r --wrap-summaries 79 --wrap-descriptions 79 .
$ autopep8 --in-place --recursive --aggressive .
$ black .
$ flake8 .
```

View File

@@ -1,3 +1,5 @@
"""Flask app to generate memes."""
import random
import os
import requests
@@ -6,17 +8,17 @@ from flask import Flask, render_template, abort, request
from QuoteEngine import Ingestor
from MemeEngine import MemeEngine
# Create the Flask application object. "__name__" tells Flask where to find templates and static files.
# Create the Flask application object. "__name__" tells Flask,
# where to find templates and static files.
app = Flask(__name__)
# Create a global MemeEngine instance that will write generated memes into "./static"
# so that the images can be served by the web server.
# Create a global MemeEngine instance that will write generated memes
# into "./static" so that the images can be served by the web server.
meme = MemeEngine("./static")
def setup():
"""Load all resources"""
"""Load all resources."""
quote_files = [
"./_data/DogQuotes/DogQuotesTXT.txt",
"./_data/DogQuotes/DogQuotesDOCX.docx",
@@ -45,7 +47,7 @@ quotes, imgs = setup()
@app.route("/")
def meme_rand():
"""Generate a random meme
"""Generate a random meme.
Steps:
- Pick a random image from imgs
@@ -63,7 +65,7 @@ def meme_rand():
@app.route("/create", methods=["GET"])
def meme_form():
"""User input for meme information
"""User input for meme information.
This route renders a form where the user can input:
- image_url: URL of the source image
@@ -75,7 +77,7 @@ def meme_form():
@app.route("/create", methods=["POST"])
def meme_post():
"""Create a user defined meme
"""Create a user defined meme.
This route:
- Reads form data sent via POST from the meme_form page
@@ -95,8 +97,8 @@ def meme_post():
tmp_file = f"tmp/{random.randint(0, 10000)}.jpg"
with open(tmp_file, "wb") as file:
file.write(image.content)
except:
print("Failed to generate meme")
except OSError as e:
print("Failed to generate meme:", e)
path = None
if os.path.exists(tmp_file):
os.remove(tmp_file)

View File

@@ -1,3 +1,5 @@
"""Generate a meme from an image and a quote."""
import os
import random
import argparse
@@ -6,7 +8,7 @@ from QuoteEngine import QuoteModel, Ingestor
def generate_meme(path=None, body=None, author=None):
"""Generate a meme given an path and a quote"""
"""Generate a meme given an path and a quote."""
img = None
quote = None
@@ -45,7 +47,8 @@ def generate_meme(path=None, body=None, author=None):
if __name__ == "__main__":
"""Add path, quote, and author arguments for CLI, then print meme generation."""
"""Add path, quote, and author arguments for CLI, then print meme
generation."""
parser = argparse.ArgumentParser(description="Meme Generator")
parser.add_argument("--path", type=str, help="Image path")
parser.add_argument("--body", type=str, help="Quote adding to meme")