Webcomics, Captions
parent
25836cdbf8
commit
dc777feea8
Binary file not shown.
180
pillow_fight.py
180
pillow_fight.py
|
@ -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()
|
Loading…
Reference in New Issue