add shepherd
This commit is contained in:
parent
f38fce1550
commit
5b86c49447
105
image_text.py
Normal file
105
image_text.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
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.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, position, text, font_filename, font_size=11, color=(0, 0, 0), max_width=None, max_height=None):
|
||||||
|
x, y = position
|
||||||
|
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, position, text, box_width, font_filename, font_size=11, color=(0, 0, 0), place='left',
|
||||||
|
justify_last_line=False):
|
||||||
|
x, y = position
|
||||||
|
lines = []
|
||||||
|
line = []
|
||||||
|
text_height = 0
|
||||||
|
text_lines = text.split('\n')
|
||||||
|
for text_line in text_lines:
|
||||||
|
words = text_line.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)
|
||||||
|
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
|
BIN
lobster.ttf
Normal file
BIN
lobster.ttf
Normal file
Binary file not shown.
10
main.py
10
main.py
@ -22,7 +22,7 @@ from config import BOT_TOKEN, SENTRY_DSN, MANAGEMENT_CHAT, DEBUG
|
|||||||
from db import get_conn, Subscriber, PersistentMapping, commit
|
from db import get_conn, Subscriber, PersistentMapping, commit
|
||||||
from morj import draw_morj
|
from morj import draw_morj
|
||||||
from send_users_list import send_users_list
|
from send_users_list import send_users_list
|
||||||
|
from shepherd import draw_shepherd
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
@ -246,6 +246,14 @@ def morj(bot: Bot, update: Update):
|
|||||||
os.unlink(fname)
|
os.unlink(fname)
|
||||||
|
|
||||||
|
|
||||||
|
def shepherd(bot: Bot, update: Update):
|
||||||
|
text = update.effective_message.text[10:]
|
||||||
|
fname = '/tmp/shepherd{}.png'.format(uuid4())
|
||||||
|
draw_shepherd(text, fname)
|
||||||
|
update.effective_message.reply_photo(open(fname, 'rb'))
|
||||||
|
os.unlink(fname)
|
||||||
|
|
||||||
|
|
||||||
def _process_message(bot: Bot, m: Message):
|
def _process_message(bot: Bot, m: Message):
|
||||||
if m.sticker or m.animation:
|
if m.sticker or m.animation:
|
||||||
delta = datetime.now() - conn.root.last_media
|
delta = datetime.now() - conn.root.last_media
|
||||||
|
112
morj.py
112
morj.py
@ -1,119 +1,9 @@
|
|||||||
#!/usr/bin/env python
|
from image_text import ImageText
|
||||||
# coding: utf-8
|
|
||||||
|
|
||||||
# Copyright 2011 Álvaro Justen [alvarojusten at gmail dot com]
|
|
||||||
# License: GPL <http://www.gnu.org/copyleft/gpl.html>
|
|
||||||
|
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
|
||||||
|
|
||||||
FONT_FILE = 'CenturyGothicBold.ttf'
|
FONT_FILE = 'CenturyGothicBold.ttf'
|
||||||
BG = 'MORJ.png'
|
BG = 'MORJ.png'
|
||||||
|
|
||||||
|
|
||||||
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, position, text, font_filename, font_size=11, color=(0, 0, 0), max_width=None, max_height=None):
|
|
||||||
x, y = position
|
|
||||||
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, position, text, box_width, font_filename, font_size=11, color=(0, 0, 0), place='left',
|
|
||||||
justify_last_line=False):
|
|
||||||
x, y = position
|
|
||||||
lines = []
|
|
||||||
line = []
|
|
||||||
text_height = 0
|
|
||||||
text_lines = text.split('\n')
|
|
||||||
for text_line in text_lines:
|
|
||||||
words = text_line.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)
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def draw_morj(text, filename):
|
def draw_morj(text, filename):
|
||||||
img = ImageText(BG)
|
img = ImageText(BG)
|
||||||
img.write_text_box((67, 70), text, box_width=800, font_filename=FONT_FILE, font_size=40, color=(255, 255, 255))
|
img.write_text_box((67, 70), text, box_width=800, font_filename=FONT_FILE, font_size=40, color=(255, 255, 255))
|
||||||
|
@ -6,6 +6,7 @@ cryptography==2.6.1
|
|||||||
future==0.17.1
|
future==0.17.1
|
||||||
idna==2.8
|
idna==2.8
|
||||||
persistent==4.4.3
|
persistent==4.4.3
|
||||||
|
Pillow==7.0.0
|
||||||
pyaes==1.6.1
|
pyaes==1.6.1
|
||||||
pycparser==2.19
|
pycparser==2.19
|
||||||
Pyrogram==0.11.0
|
Pyrogram==0.11.0
|
||||||
|
BIN
shepherd.jpg
Normal file
BIN
shepherd.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
11
shepherd.py
Normal file
11
shepherd.py
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
from image_text import ImageText
|
||||||
|
|
||||||
|
FONT_FILE = 'lobster.ttf'
|
||||||
|
BG = 'shepherd.jpg'
|
||||||
|
|
||||||
|
|
||||||
|
def draw_shepherd(text, filename):
|
||||||
|
img = ImageText(BG)
|
||||||
|
img.write_text_box((74, 310), text, box_width=600, font_filename=FONT_FILE, font_size=40, color=(0, 0, 0),
|
||||||
|
place='center')
|
||||||
|
img.save(filename)
|
Loading…
Reference in New Issue
Block a user