first
commit
2f027e1986
|
@ -0,0 +1 @@
|
||||||
|
__pycache__/image_utils.cpython-39.pyc
|
|
@ -0,0 +1,276 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
#I stole this :P
|
||||||
|
|
||||||
|
# Copyright 2011 Álvaro Justen [alvarojusten at gmail dot com]
|
||||||
|
# License: GPL <http://www.gnu.org/copyleft/gpl.html>
|
||||||
|
|
||||||
|
# from PIL import Image
|
||||||
|
# from PIL import ImageDraw
|
||||||
|
# from PIL import ImageFont
|
||||||
|
|
||||||
|
|
||||||
|
# class ImageText(object):
|
||||||
|
# def __init__(self, filename_or_size, mode='RGBA', background=(0, 0, 0, 0),
|
||||||
|
# encoding='utf8'):
|
||||||
|
# if isinstance(filename_or_size, str):
|
||||||
|
# self.filename = filename_or_size
|
||||||
|
# self.image = Image.open(self.filename)
|
||||||
|
# self.size = self.image.size
|
||||||
|
# elif isinstance(filename_or_size, (list, tuple)):
|
||||||
|
# self.size = filename_or_size
|
||||||
|
# self.image = Image.new(mode, self.size, color=background)
|
||||||
|
# self.filename = None
|
||||||
|
# self.draw = ImageDraw.Draw(self.image)
|
||||||
|
# self.encoding = encoding
|
||||||
|
|
||||||
|
# def save(self, filename=None):
|
||||||
|
# self.image.save(filename or self.filename)
|
||||||
|
|
||||||
|
# def get_font_size(self, text, font, max_width=None, max_height=None):
|
||||||
|
# if max_width is None and max_height is None:
|
||||||
|
# raise ValueError('You need to pass max_width or max_height')
|
||||||
|
# font_size = 1
|
||||||
|
# text_size = self.get_text_size(font, font_size, text)
|
||||||
|
# if (max_width is not None and text_size[0] > max_width) or \
|
||||||
|
# (max_height is not None and text_size[1] > max_height):
|
||||||
|
# raise ValueError("Text can't be filled in only (%dpx, %dpx)" % \
|
||||||
|
# text_size)
|
||||||
|
# while True:
|
||||||
|
# if (max_width is not None and text_size[0] >= max_width) or \
|
||||||
|
# (max_height is not None and text_size[1] >= max_height):
|
||||||
|
# return font_size - 1
|
||||||
|
# font_size += 1
|
||||||
|
# text_size = self.get_text_size(font, font_size, text)
|
||||||
|
|
||||||
|
# def write_text(self, xy, text, font_filename, font_size=11,
|
||||||
|
# color=(0, 0, 0), max_width=None, max_height=None):
|
||||||
|
# x, y = xy
|
||||||
|
# if font_size == 'fill' and \
|
||||||
|
# (max_width is not None or max_height is not None):
|
||||||
|
# font_size = self.get_font_size(text, font_filename, max_width,
|
||||||
|
# max_height)
|
||||||
|
# text_size = self.get_text_size(font_filename, font_size, text)
|
||||||
|
# font = ImageFont.truetype(font_filename, font_size)
|
||||||
|
# if x == 'center':
|
||||||
|
# x = (self.size[0] - text_size[0]) / 2
|
||||||
|
# if y == 'center':
|
||||||
|
# y = (self.size[1] - text_size[1]) / 2
|
||||||
|
# self.draw.text((x, y), text, font=font, fill=color)
|
||||||
|
# return text_size
|
||||||
|
|
||||||
|
# def get_text_size(self, font_filename, font_size, text):
|
||||||
|
# font = ImageFont.truetype(font_filename, font_size)
|
||||||
|
# return font.getsize(text)
|
||||||
|
|
||||||
|
# def write_text_box(self, xy, text, box_width, font_filename,
|
||||||
|
# font_size=11, color=(0, 0, 0), place='left',
|
||||||
|
# justify_last_line=False):
|
||||||
|
# x, y = xy
|
||||||
|
# lines = []
|
||||||
|
# line = []
|
||||||
|
# words = text.split()
|
||||||
|
# for word in words:
|
||||||
|
# new_line = ' '.join(line + [word])
|
||||||
|
# size = self.get_text_size(font_filename, font_size, new_line)
|
||||||
|
# text_height = size[1]
|
||||||
|
# if size[0] <= box_width:
|
||||||
|
# line.append(word)
|
||||||
|
# else:
|
||||||
|
# lines.append(line)
|
||||||
|
# line = [word]
|
||||||
|
# if line:
|
||||||
|
# lines.append(line)
|
||||||
|
# lines = [' '.join(line) for line in lines if line]
|
||||||
|
# height = y
|
||||||
|
# for index, line in enumerate(lines):
|
||||||
|
# height += text_height
|
||||||
|
# if place == 'left':
|
||||||
|
# self.write_text((x, height), line, font_filename, font_size,
|
||||||
|
# color)
|
||||||
|
# elif place == 'right':
|
||||||
|
# total_size = self.get_text_size(font_filename, font_size, line)
|
||||||
|
# x_left = x + box_width - total_size[0]
|
||||||
|
# self.write_text((x_left, height), line, font_filename,
|
||||||
|
# font_size, color)
|
||||||
|
# elif place == 'center':
|
||||||
|
# total_size = self.get_text_size(font_filename, font_size, line)
|
||||||
|
# x_left = int(x + ((box_width - total_size[0]) / 2))
|
||||||
|
# self.write_text((x_left, height), line, font_filename,
|
||||||
|
# font_size, color)
|
||||||
|
# elif place == 'justify':
|
||||||
|
# words = line.split()
|
||||||
|
# if (index == len(lines) - 1 and not justify_last_line) or \
|
||||||
|
# len(words) == 1:
|
||||||
|
# self.write_text((x, height), line, font_filename, font_size,
|
||||||
|
# color)
|
||||||
|
# continue
|
||||||
|
# line_without_spaces = ''.join(words)
|
||||||
|
# total_size = self.get_text_size(font_filename, font_size,
|
||||||
|
# line_without_spaces)
|
||||||
|
# space_width = (box_width - total_size[0]) / (len(words) - 1.0)
|
||||||
|
# start_x = x
|
||||||
|
# for word in words[:-1]:
|
||||||
|
# self.write_text((start_x, height), word, font_filename,
|
||||||
|
# font_size, color)
|
||||||
|
# word_size = self.get_text_size(font_filename, font_size,
|
||||||
|
# word)
|
||||||
|
# start_x += word_size[0] + space_width
|
||||||
|
# last_word_size = self.get_text_size(font_filename, font_size,
|
||||||
|
# words[-1])
|
||||||
|
# last_word_x = x + box_width - last_word_size[0]
|
||||||
|
# self.write_text((last_word_x, height), words[-1], font_filename,
|
||||||
|
# font_size, color)
|
||||||
|
# return (box_width, height - y)
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
|
|
||||||
|
class ImageText(object):
|
||||||
|
def __init__(self, filename_or_size, mode='RGBA', background=(0, 0, 0, 0),
|
||||||
|
encoding='utf8'):
|
||||||
|
if isinstance(filename_or_size, str):
|
||||||
|
self.filename = filename_or_size
|
||||||
|
self.image = Image.open(self.filename)
|
||||||
|
self.initial_image = Image.open(self.filename)
|
||||||
|
self.size = self.image.size
|
||||||
|
elif isinstance(filename_or_size, (list, tuple)):
|
||||||
|
self.size = filename_or_size
|
||||||
|
self.image = Image.new(mode, self.size, color=background)
|
||||||
|
self.initial_image = Image.new(mode, self.size, color=background)
|
||||||
|
self.filename = None
|
||||||
|
self.draw = ImageDraw.Draw(self.image)
|
||||||
|
self.encoding = encoding
|
||||||
|
|
||||||
|
def reset_image(self):
|
||||||
|
self.image = self.initial_image
|
||||||
|
self.draw = ImageDraw.Draw(self.image)
|
||||||
|
|
||||||
|
def save(self, filename=None):
|
||||||
|
self.image.save(filename or self.filename)
|
||||||
|
|
||||||
|
def get_image(self):
|
||||||
|
return self.image
|
||||||
|
|
||||||
|
def get_font_size(self, text, font, max_width=None, max_height=None):
|
||||||
|
if max_width is None and max_height is None:
|
||||||
|
raise ValueError('You need to pass max_width or max_height')
|
||||||
|
font_size = 1
|
||||||
|
text_size = self.get_text_size(font, font_size, text)
|
||||||
|
if (max_width is not None and text_size[0] > max_width) or \
|
||||||
|
(max_height is not None and text_size[1] > max_height):
|
||||||
|
raise ValueError("Text can't be filled in only (%dpx, %dpx)" % \
|
||||||
|
text_size)
|
||||||
|
while True:
|
||||||
|
if (max_width is not None and text_size[0] >= max_width) or \
|
||||||
|
(max_height is not None and text_size[1] >= max_height):
|
||||||
|
return font_size - 1
|
||||||
|
font_size += 1
|
||||||
|
text_size = self.get_text_size(font, font_size, text)
|
||||||
|
|
||||||
|
def write_text(self, xy, text, font_filename, font_size=11,
|
||||||
|
color=(0, 0, 0), max_width=None, max_height=None):
|
||||||
|
x, y = xy
|
||||||
|
if isinstance(text, str):
|
||||||
|
try:
|
||||||
|
text = text.decode(self.encoding)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
if font_size == 'fill' and \
|
||||||
|
(max_width is not None or max_height is not None):
|
||||||
|
font_size = self.get_font_size(text, font_filename, max_width,
|
||||||
|
max_height)
|
||||||
|
text_size = self.get_text_size(font_filename, font_size, text)
|
||||||
|
font = ImageFont.truetype(font_filename, font_size)
|
||||||
|
if x == 'center':
|
||||||
|
x = (self.size[0] - text_size[0]) / 2
|
||||||
|
if y == 'center':
|
||||||
|
y = (self.size[1] - text_size[1]) / 2
|
||||||
|
self.draw.text((x, y), text, font=font, fill=color)
|
||||||
|
return text_size
|
||||||
|
|
||||||
|
def get_text_size(self, font_filename, font_size, text):
|
||||||
|
font = ImageFont.truetype(font_filename, font_size)
|
||||||
|
return font.getsize(text)
|
||||||
|
|
||||||
|
def fill_text_box(self, xy, text, box_width, box_height, font_filename,
|
||||||
|
start_font_size=1, color=(0,0,0), place='left',
|
||||||
|
justify_last_line=False):
|
||||||
|
font_size = start_font_size
|
||||||
|
while True:
|
||||||
|
width, height, box_width = self.write_text_box(xy, text, box_width,
|
||||||
|
font_filename, font_size, color, place)
|
||||||
|
|
||||||
|
if (width >= box_width) or (height >= box_height):
|
||||||
|
font_size -= 1
|
||||||
|
self.reset_image()
|
||||||
|
self.write_text_box(xy, text, box_width,
|
||||||
|
font_filename, font_size, color, place)
|
||||||
|
break
|
||||||
|
|
||||||
|
font_size += 1
|
||||||
|
|
||||||
|
return (box_width, box_height)
|
||||||
|
|
||||||
|
def write_text_box(self, xy, text, box_width, font_filename,
|
||||||
|
font_size=11, color=(0, 0, 0), place='left',
|
||||||
|
justify_last_line=False):
|
||||||
|
x, y = xy
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
line = []
|
||||||
|
words = text.split()
|
||||||
|
for word in words:
|
||||||
|
new_line = ' '.join(line + [word])
|
||||||
|
size = self.get_text_size(font_filename, font_size, new_line)
|
||||||
|
text_height = size[1]
|
||||||
|
if size[0] <= box_width:
|
||||||
|
line.append(word)
|
||||||
|
else:
|
||||||
|
lines.append(line)
|
||||||
|
line = [word]
|
||||||
|
if line:
|
||||||
|
lines.append(line)
|
||||||
|
lines = [' '.join(line) for line in lines if line]
|
||||||
|
|
||||||
|
height = y
|
||||||
|
for index, line in enumerate(lines):
|
||||||
|
if place == 'left':
|
||||||
|
total_size = self.get_text_size(font_filename, font_size, line)
|
||||||
|
self.write_text((x, height), line, font_filename, font_size,
|
||||||
|
color)
|
||||||
|
elif place == 'right':
|
||||||
|
total_size = self.get_text_size(font_filename, font_size, line)
|
||||||
|
x_left = x + box_width - total_size[0]
|
||||||
|
self.write_text((x_left, height), line, font_filename,
|
||||||
|
font_size, color)
|
||||||
|
elif place == 'center':
|
||||||
|
total_size = self.get_text_size(font_filename, font_size, line)
|
||||||
|
x_left = int(x + ((box_width - total_size[0]) / 2))
|
||||||
|
self.write_text((x_left, height), line, font_filename,
|
||||||
|
font_size, color)
|
||||||
|
elif place == 'justify':
|
||||||
|
words = line.split()
|
||||||
|
if (index == len(lines) - 1 and not justify_last_line) or \
|
||||||
|
len(words) == 1:
|
||||||
|
self.write_text((x, height), line, font_filename, font_size,
|
||||||
|
color)
|
||||||
|
continue
|
||||||
|
line_without_spaces = ''.join(words)
|
||||||
|
total_size = self.get_text_size(font_filename, font_size,
|
||||||
|
line_without_spaces)
|
||||||
|
space_width = (box_width - total_size[0]) / (len(words) - 1.0)
|
||||||
|
start_x = x
|
||||||
|
for word in words[:-1]:
|
||||||
|
self.write_text((start_x, height), word, font_filename,
|
||||||
|
font_size, color)
|
||||||
|
word_size = self.get_text_size(font_filename, font_size,
|
||||||
|
word)
|
||||||
|
start_x += word_size[0] + space_width
|
||||||
|
last_word_size = self.get_text_size(font_filename, font_size,
|
||||||
|
words[-1])
|
||||||
|
last_word_x = x + box_width - last_word_size[0]
|
||||||
|
self.write_text((last_word_x, height), words[-1], font_filename,
|
||||||
|
font_size, color)
|
||||||
|
height += text_height
|
||||||
|
return (total_size[0], height - y, box_width)
|
Binary file not shown.
|
@ -0,0 +1,69 @@
|
||||||
|
from PIL import Image
|
||||||
|
from PIL import ImageDraw
|
||||||
|
from PIL import ImageFont
|
||||||
|
from PIL import ImageOps
|
||||||
|
import requests
|
||||||
|
import io
|
||||||
|
from image_utils import ImageText
|
||||||
|
|
||||||
|
MARGIN_PERCENT = 0.2
|
||||||
|
|
||||||
|
def create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2):
|
||||||
|
left_image = get_emoji_from_rdrama(emoji1)
|
||||||
|
right_image = get_emoji_from_rdrama(emoji2)
|
||||||
|
|
||||||
|
left_size_x, left_size_y = left_image.size
|
||||||
|
right_size_x, right_size_y = right_image.size
|
||||||
|
|
||||||
|
#We want the dimensions of the smaller one.
|
||||||
|
if left_size_x > right_size_x:
|
||||||
|
base_size_x = right_size_x
|
||||||
|
base_size_y = right_size_y
|
||||||
|
#left_image = left_image.resize((base_size_x, base_size_y))
|
||||||
|
else:
|
||||||
|
base_size_x = left_size_x
|
||||||
|
base_size_y = left_size_y
|
||||||
|
#right_image = right_image.resize((base_size_x, base_size_y))
|
||||||
|
|
||||||
|
margin_size = int(MARGIN_PERCENT*base_size_x)
|
||||||
|
total_image_width = 2*base_size_x + margin_size
|
||||||
|
|
||||||
|
#left_image = ImageOps.mirror(left_image)
|
||||||
|
base = Image.new(mode="RGB", size=(total_image_width,total_image_width), color=(255,255,255))
|
||||||
|
base.paste(left_image, (0,0), left_image)
|
||||||
|
base.paste(right_image, (margin_size+base_size_x,0), right_image)
|
||||||
|
|
||||||
|
left_caption_box = ImageText((left_size_x, total_image_width-left_size_y))
|
||||||
|
left_caption_box.fill_text_box((0,0), caption1, left_size_x, total_image_width-left_size_y, font_filename="impact.ttf")
|
||||||
|
base.paste(left_caption_box.image, (0, left_size_y), left_caption_box.image)
|
||||||
|
right_caption_box = ImageText((right_size_x, total_image_width-right_size_y))
|
||||||
|
right_caption_box.fill_text_box((0,0), caption2, right_size_x, total_image_width-right_size_y, font_filename="impact.ttf")
|
||||||
|
base.paste(right_caption_box.image, (left_size_x+margin_size, right_size_y), right_caption_box.image)
|
||||||
|
|
||||||
|
return base
|
||||||
|
|
||||||
|
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()
|
||||||
|
imageDraw.multiline_text()
|
||||||
|
|
||||||
|
def get_emoji_from_rdrama(emoji_name):
|
||||||
|
return get_image_file_from_url(f"https://www.rdrama.net/e/{emoji_name}.webp")
|
||||||
|
|
||||||
|
def get_image_file_from_url(url):
|
||||||
|
r = requests.get(url)
|
||||||
|
image_file = io.BytesIO(r.content)
|
||||||
|
im = Image.open(image_file)
|
||||||
|
return im
|
||||||
|
|
||||||
|
#get_emoji_from_rdrama("zoomersoy").show()
|
||||||
|
|
||||||
|
create_soy_vs_chad_meme("marseywhirlyhat", "marseyaynrand", "For twelve years, you have been asking: Who is John Galt? This is John Galt speaking. I am the man who loves his life. I am the man who does not sacrifice his love or his values. I am the man who has deprived you of victims and thus has destroyed your world, and if you wish to know why you are perishing—you who dread knowledge—I am the man who will now tell you.” The chief engineer was the only one able to move; he ran to a television set and struggled frantically with its dials. But the screen remained empty; the speaker had not chosen to be seen. Only his voice filled the airways of the country—of the world, thought the chief engineer—sounding as if he were speaking here, in this room, not to a group, but to one man; it was not the tone of addressing a meeting, but the tone of addressing a mind.", "You have heard it said that this is an age of moral crisis. You have said it yourself, half in fear, half in hope that the words had no meaning. You have cried that man’s sins are destroying the world and you have cursed human nature for its unwillingness to practice the virtues you demanded. Since virtue, to you, consists of sacrifice, you have demanded more sacrifices at every successive disaster. In the name of a return to morality, you have sacrificed all those evils which you held as the cause of your plight. You have sacrificed justice to mercy. You have sacrificed independence to unity. You have sacrificed reason to faith. You have sacrificed wealth to need. You have sacrificed self-esteem to self-denial. You have sacrificed happiness to duty.").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()
|
Binary file not shown.
Loading…
Reference in New Issue