Webcomics, Captions

master
HeyMoon 2022-08-11 19:34:44 -05:00
parent 25836cdbf8
commit dc777feea8
2 changed files with 155 additions and 25 deletions

BIN
Little Story.ttf 100644

Binary file not shown.

View File

@ -1,3 +1,4 @@
import math
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
@ -5,21 +6,22 @@ from PIL import ImageOps
import requests
import io
from image_utils import ImageText
LEFT_MARGIN_COLUMN = 20
CONTENT_COLUMN = 300
MIDDLE_MARGIN_COLUMN = 80
RIGHT_MARGIN_COLUMN = LEFT_MARGIN_COLUMN
TOP_MARGIN_ROW = 80
IMAGE_ROW = 300
MIDDLE_MARGIN_ROW = 20
TEXT_ROW = 100
BOTTOM_MARGIN_ROW = 200
total_image_size_x = 2*CONTENT_COLUMN + LEFT_MARGIN_COLUMN + RIGHT_MARGIN_COLUMN + MIDDLE_MARGIN_COLUMN
total_image_size_y = TOP_MARGIN_ROW + IMAGE_ROW + MIDDLE_MARGIN_ROW + TEXT_ROW + BOTTOM_MARGIN_ROW
from os.path import exists
def create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2):
LEFT_MARGIN_COLUMN = 20
CONTENT_COLUMN = 300
MIDDLE_MARGIN_COLUMN = 80
RIGHT_MARGIN_COLUMN = LEFT_MARGIN_COLUMN
TOP_MARGIN_ROW = 80
IMAGE_ROW = 300
MIDDLE_MARGIN_ROW = 20
TEXT_ROW = 100
BOTTOM_MARGIN_ROW = 200
total_image_size_x = 2*CONTENT_COLUMN + LEFT_MARGIN_COLUMN + RIGHT_MARGIN_COLUMN + MIDDLE_MARGIN_COLUMN
total_image_size_y = TOP_MARGIN_ROW + IMAGE_ROW + MIDDLE_MARGIN_ROW + TEXT_ROW + BOTTOM_MARGIN_ROW
left_image = get_emoji_from_rdrama(emoji1)
right_image = get_emoji_from_rdrama(emoji2)
@ -41,7 +43,116 @@ def create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2):
add_text(base, caption2, (CONTENT_COLUMN, TEXT_ROW), (LEFT_MARGIN_COLUMN+CONTENT_COLUMN+MIDDLE_MARGIN_COLUMN, TOP_MARGIN_ROW+IMAGE_ROW+MIDDLE_MARGIN_ROW))
return add_watermark(base)
class WebcomicPanel():
PANEL_SIZE = 400
FONT = "Little Story.ttf"
def __init__(self):
pass
def create_image(self) -> Image:
return Image.new(mode="RGB", size=(self.PANEL_SIZE,self.PANEL_SIZE), color=(255,255,255))
class OneCharacterWebcomicPanel(WebcomicPanel):
def __init__(self, emoji, caption):
self.emoji = emoji
self.caption = caption
def create_image(self) -> Image:
base = super().create_image()
panel_size_x, panel_size_y = base.size
# We put marsey in the bottom left quadrant
emoji_region_x_size = int(panel_size_x/2)
emoji_region_y_size = int(panel_size_y/2)
emoji_placement_position_x = 0
emoji_placement_position_y = int(panel_size_y/2)
emoji = get_emoji_from_rdrama(self.emoji)
center_and_paste(base, emoji, (emoji_placement_position_x, emoji_placement_position_y), (emoji_region_x_size, emoji_region_y_size))
# We put the text in the top half of the panel.
text_region_x_size = int(panel_size_x)
text_region_y_size = int(panel_size_y/2)
add_text(base, self.caption, (text_region_x_size, text_region_y_size), (0,0), font=super().FONT)
return add_border_to_image(base)
class TwoCharacterWebcomicPanel(WebcomicPanel):
def __init__(self, left_emoji, left_caption, right_emoji, right_caption):
self.left_emoji = left_emoji
self.left_caption = left_caption
self.right_emoji = right_emoji
self.right_caption = right_caption
def create_image(self) -> Image:
base = super().create_image()
panel_size_x, panel_size_y = base.size
# We put the left marsey in the bottom left quadrant
left_emoji_region_x_size = int(panel_size_x/2)
left_emoji_region_y_size = int(panel_size_y/2)
left_emoji_placement_position_x = 0
left_emoji_placement_position_y = int(panel_size_y/2)
left_emoji = get_emoji_from_rdrama(self.left_emoji)
center_and_paste(base, left_emoji, (left_emoji_placement_position_x, left_emoji_placement_position_y), (left_emoji_region_x_size, left_emoji_region_y_size))
# We put the right marsey in the bottom right quadrant
right_emoji_region_x_size = int(panel_size_x/2)
right_emoji_region_y_size = int(panel_size_y/2)
right_emoji_placement_position_x = int(panel_size_x/2)
right_emoji_placement_position_y = int(panel_size_y/2)
right_emoji = get_emoji_from_rdrama(self.right_emoji)
center_and_paste(base, right_emoji, (right_emoji_placement_position_x, right_emoji_placement_position_y), (right_emoji_region_x_size, right_emoji_region_y_size))
#Each text caption will get 5/8 of the width, and 1/4 of the height of the panel.
#The left caption will be all the way to the left. The right caption will be 3/8 to the right.
CAPTION_UNITS = 5
CAPTION_DIVISOR = 8
# We put the text in the top half of the panel.
left_text_region_x_size = int(CAPTION_UNITS*(panel_size_x/CAPTION_DIVISOR))
left_text_region_y_size = int(panel_size_y/4)
left_text_region_x_position = 0
left_text_region_y_position = 0
add_text(base, self.left_caption, (left_text_region_x_size, left_text_region_y_size), (left_text_region_x_position,left_text_region_y_position), font=super().FONT)
# We put the text in the top half of the panel.
right_text_region_x_size = int(CAPTION_UNITS*(panel_size_x/CAPTION_DIVISOR))
right_text_region_y_size = int(panel_size_y/4)
right_text_region_x_position = int((CAPTION_DIVISOR-CAPTION_UNITS)*(panel_size_x/8))
right_text_region_y_position = int(panel_size_y/4)
add_text(base, self.right_caption, (right_text_region_x_size, right_text_region_y_size), (right_text_region_x_position,right_text_region_y_position), font=super().FONT)
return add_border_to_image(base)
class TitleCardWebcomicPanel(WebcomicPanel):
def __init__(self, caption):
self.caption = caption
def create_image(self) -> Image:
base = super().create_image()
add_text(base, self.caption, base.size, (0,0), font=super().FONT)
return add_border_to_image(base)
def create_webcomic(layout : 'list[WebcomicPanel]'):
assumed_panel_x_size, assumed_panel_y_size = layout[0].create_image().size
total_image_x_size = assumed_panel_x_size * 2
total_image_y_size = assumed_panel_x_size * math.ceil(len(layout)/2)
image = Image.new(mode="RGB", size=(total_image_x_size, total_image_y_size), color=(255,255,255))
for i in range(len(layout)):
panel = layout[i]
x = i%2
y = math.floor(i/2)
image.paste(panel.create_image(), (x*assumed_panel_x_size, y*assumed_panel_y_size))
return add_watermark(image)
def add_text(base : Image, caption : str, region_size : tuple[int, int], coordinates : tuple[int, int], font : str= "arial.ttf"):
if caption == "":
return
region_x_size, region_y_size = region_size
line_image = ImageText((region_x_size, region_y_size))
line_image.fill_text_box((0,0), caption, region_x_size, region_y_size, font_filename=font)
@ -53,7 +164,7 @@ def add_watermark(image : Image):
base = Image.new(mode="RGB", size=(image_size_x, image_size_y + WATERMARK_HEIGHT), color=(255,255,255))
base.paste(image)
marsey = get_emoji_from_rdrama("marseybangfast")
marsey = get_emoji_from_rdrama("marseyjamming")
marsey = ImageOps.contain(marsey, (WATERMARK_HEIGHT, WATERMARK_HEIGHT))
base.paste(marsey, (0, image_size_y), marsey)
@ -65,6 +176,8 @@ def add_watermark(image : Image):
return base
def center_and_paste(base : Image, to_paste : Image, coordinates: tuple[int, int], box_size : tuple[int, int]):
to_paste = ImageOps.contain(to_paste, box_size)
image_size_x, image_size_y = to_paste.size
box_size_x, box_size_y = box_size
@ -80,6 +193,19 @@ def center_and_paste(base : Image, to_paste : Image, coordinates: tuple[int, int
base.paste(to_paste, (x, y), to_paste)
def add_border_to_image(image : Image, thickness : int = 5):
# image_draw = ImageDraw.Draw(image)
# image_x_size, image_y_size = image.size
# inner_rectangle_x_size, inner_rectangle_y_size = image_x_size - 2*thickness, image_y_size - 2*thickness
# image_draw.rectangle([(0,0),(image_x_size, image_y_size)], fill="black")
# image_draw.rectangle([(thickness, thickness),(image_x_size-thickness, image_y_size-thickness)], fill="white")
inner_image_x_size, inner_image_y_size = image.size
outer_image_x_size, outer_image_y_size = inner_image_x_size + 2*thickness, inner_image_y_size + 2*thickness
outside_image = Image.new(mode="RGB", size=(outer_image_x_size,outer_image_y_size), color=(0,0,0))
outside_image.paste(image, (thickness, thickness))
return outside_image
def wrap_text_for_font(text, region_size, font_size) -> Image:
image = Image.new(mode="RGB", size=region_size, color=(255,255,255))
imageDraw = ImageDraw.ImageDraw()
@ -91,7 +217,12 @@ def get_emoji_from_rdrama(emoji_name):
if '!' in emoji_name:
cleaned_emoji_name = cleaned_emoji_name.replace("!", "")
should_flip = True
image = get_image_file_from_url(f"https://www.rdrama.net/e/{cleaned_emoji_name}.webp")
if (exists(f"emoji_cache/{cleaned_emoji_name}.webp")):
image = Image.open(f"emoji_cache/{cleaned_emoji_name}.webp")
else:
image = get_image_file_from_url(f"https://www.rdrama.net/e/{cleaned_emoji_name}.webp")
image.save(f"emoji_cache/{cleaned_emoji_name}.webp")
if should_flip:
image = ImageOps.mirror(image)
return image
@ -102,14 +233,13 @@ def get_image_file_from_url(url):
im = Image.open(image_file)
return im
#get_emoji_from_rdrama("zoomersoy").show()
#create_soy_vs_chad_meme("bigsmilesoyjak", "!marseyshooting", "I have fun new toys and games for your children", "Die").show()
create_soy_vs_chad_meme("bigsmilesoyjak", "!marseyshooting", "I have fun new toys and games for your children", "Die").show()
# base_image = Image.new(mode="RGB", size=(1000,1000), color=(255,255,255))
# marppy_image = Image.open("marppy.webp")
# base_image.paste(marppy_image, (0,0), marppy_image)
# I1 = ImageDraw.Draw(base_image)
# font = ImageFont.truetype("impact.ttf", 65)
# I1.text((300, 0), "GO HOME GAMER GIRL", font=font, fill=(255, 0, 0))
# base_image.show()
create_webcomic([
TwoCharacterWebcomicPanel("soyjak", "Black people deserve the rope", "marseyconfused", "Why?"),
TwoCharacterWebcomicPanel("seethejak", "Because they are degenerate!!!", "marseysmug", "Kinda like you?"),
OneCharacterWebcomicPanel("soycry", "No!! I am a pure aryan white boy and I am special Hitler told me so, so fuck off you nigger cunt. God I hate you so much, if I commit suicide its gonna be your fault, fuck you"),
TitleCardWebcomicPanel("One Hour Later..."),
TwoCharacterWebcomicPanel("marseytombstone", "", "!marseycry", "He had so much to live for"),
OneCharacterWebcomicPanel("marseylaugh", "Just Kidding!")
]).show()