You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
6.1 KiB
184 lines
6.1 KiB
from .abc import Meme |
|
from PIL import Image, ImageDraw, ImageFont |
|
import typing |
|
|
|
from pseudbot.meme.post import Post |
|
from pseudbot.util import ( |
|
alpha_comp_prep, |
|
circle_pfp, |
|
get_iphone_time_s, |
|
text_wrap, |
|
tuple_add, |
|
) |
|
|
|
|
|
class PhoneScreenshot(Meme): |
|
from .post_styles import styles, time_style |
|
|
|
def __init__( |
|
self, |
|
top_text: dict = None, |
|
bottom_text: str = None, |
|
style: str = "discord", |
|
width: int = 1200, |
|
height: int = 2340, |
|
notification: str = None, |
|
): |
|
self.top_text = top_text |
|
self.bottom_text = bottom_text |
|
self.style = style |
|
self.width = width |
|
self.height = height |
|
self.notification = notification |
|
|
|
self.style_methods = {"discord": self.mk_pixmap} |
|
|
|
self.init_style_posts() |
|
|
|
if self.notification is not None: |
|
self.notification_style = { |
|
"offset": (102, 91), |
|
"no_text_img": "templates/iphone/iphone-noti-grindr-text.png", |
|
"icon": { |
|
"offset": (26, 34), |
|
"size": (62, 62), |
|
"files": { |
|
"grindr": "templates/iphone/icons/notification/grindr.png" |
|
}, |
|
}, |
|
"text": { |
|
"app_name": { |
|
"font": "phone_sans", |
|
"style": "Regular", |
|
"size": 35, |
|
"offset": (106, 53), |
|
}, |
|
"heading": { |
|
"font": "phone_sans", |
|
"style": "Regular", |
|
"size": 35, |
|
"offset": (34, 128), |
|
}, |
|
"body": { |
|
"font": "phone_sans", |
|
"style": "Regular", |
|
"size": 35, |
|
"offset": (34, 181), |
|
}, |
|
}, |
|
} |
|
|
|
def overlay_noti(base_img: Image) -> Image: |
|
return base_img |
|
|
|
def mk_bars(self) -> Image: |
|
base_img = Image.new("RGBA", (self.width, self.height), (0, 0, 0, 0)) |
|
|
|
for bar in self.styles[self.style]["bars"]: |
|
is_top = False |
|
is_bottom = False |
|
do_time = False |
|
bg_img_path = bar["bg_img"] |
|
|
|
if "top" in bar: |
|
if bar["top"] is True: |
|
is_top = True |
|
do_time = True |
|
if self.notification is not None: |
|
do_time = False |
|
if "alt_bg_img" in bar: |
|
bg_img_path = self.bar["alt_bg_img"] |
|
|
|
if "bottom" in bar: |
|
if bar["bottom"] is True: |
|
is_bottom = True |
|
|
|
with Image.open(bg_img_path).convert("RGBA") as _bar_img: |
|
with alpha_comp_prep( |
|
Image.open(bg_img_path).convert("RGBA"), |
|
size=base_img.size, |
|
offset=bar["offset"], |
|
) as bar_img: |
|
if "text" in bar: |
|
try: |
|
if bar["text"]["content"] in self.top_text: |
|
if "format" in bar["text"]: |
|
bar_text = bar["text"]["format"].replace( |
|
"%%%", |
|
self.top_text[bar["text"]["content"]], |
|
) |
|
else: |
|
bar_text = self.top_text[ |
|
bar["text"]["content"] |
|
] |
|
else: |
|
bar_text = bar["text"]["default"] |
|
except KeyError: |
|
bar_text = "default text" |
|
|
|
bar_img = self.draw_text( |
|
img=bar_img, |
|
text=bar_text, |
|
offset=tuple_add( |
|
bar["text"]["offset"], bar["offset"] |
|
), |
|
size=bar["text"]["size"], |
|
fill=bar["text"]["color"], |
|
variation=bar["text"]["style"], |
|
fontname=bar["text"]["font"], |
|
) |
|
|
|
if do_time is True: |
|
bar_img = self.draw_text( |
|
img=bar_img, |
|
text=get_iphone_time_s(), |
|
offset=self.time_style["offset"], |
|
size=self.time_style["size"], |
|
fill=self.time_style["fill"][self.style], |
|
variation=self.time_style["style"], |
|
fontname=self.time_style["font"], |
|
) |
|
|
|
base_img = Image.alpha_composite(base_img, bar_img) |
|
|
|
if is_bottom is True: |
|
self.bottom_y_offset = 0 - _bar_img.size[1] |
|
|
|
if self.notification is not None: |
|
base_img = self.overlay_noti(base_img) |
|
|
|
return base_img |
|
|
|
def arrange_posts(self) -> Image: |
|
post_base = Image.new( |
|
"RGBA", |
|
(self.width, self.height), |
|
self.styles[self.style]["background"], |
|
) |
|
|
|
x_offset = 33 |
|
y_offset = self.height |
|
|
|
if hasattr(self, "bottom_y_offset"): |
|
y_offset = y_offset + self.bottom_y_offset |
|
|
|
for post in reversed(self.posts): |
|
p = Post( |
|
top_text={"posts": [post]}, |
|
bottom_text=self.bottom_text, |
|
style=self.style, |
|
) |
|
post_img = p.get_pixmap() |
|
y_offset = y_offset - post_img.size[1] |
|
post_base.paste(post_img, box=(x_offset, y_offset)) |
|
|
|
if y_offset < 0: |
|
break |
|
|
|
return post_base |
|
|
|
def mk_pixmap(self): |
|
bars = self.mk_bars() # Must be done before making posts! |
|
posts = self.arrange_posts() |
|
|
|
self.image = Image.alpha_composite(posts, bars)
|
|
|