|
4 | 4 | from discord import app_commands |
5 | 5 | from discord.ext import commands |
6 | 6 | from bs4 import BeautifulSoup as bs |
7 | | -from PIL import Image, ImageDraw, ImageFont |
8 | 7 |
|
9 | | -class QuoteImageCreator: |
10 | | - def __init__(self, background_image_path): |
11 | | - self.background_image = Image.open(background_image_path) |
12 | | - self.draw = ImageDraw.Draw(self.background_image) |
13 | | - self.quote_font = self.load_font('timesi.ttf', size=16) |
14 | | - self.author_font = self.load_font('timesbi.ttf', size=24) |
15 | | - self.left_half_width = self.background_image.width // 2 |
16 | | - self.max_text_height = self.background_image.height * 0.8 # 80% вертикали |
17 | | - |
18 | | - def load_font(self, font_path, size): |
19 | | - try: |
20 | | - return ImageFont.truetype(font_path, size) |
21 | | - except IOError: |
22 | | - return ImageFont.load_default() |
23 | | - |
24 | | - def split_line(self, line, font, max_width): |
25 | | - words = line.split() |
26 | | - current_line = "" |
27 | | - result_lines = [] |
28 | | - for word in words: |
29 | | - test_line = current_line + " " + word if current_line else word |
30 | | - if self.draw.textbbox((0, 0), test_line, font=font)[2] <= max_width: |
31 | | - current_line = test_line |
32 | | - else: |
33 | | - result_lines.append(current_line) |
34 | | - current_line = word |
35 | | - if current_line: |
36 | | - result_lines.append(current_line) |
37 | | - return result_lines |
38 | | - |
39 | | - def create_quote_image(self, content, author): |
40 | | - content = f"\"{content}\"" |
41 | | - author = f"(c) {author}" |
42 | | - if len(author) > 30: |
43 | | - author = author[:30] + "..." |
44 | | - |
45 | | - text_lines = self.split_text(content) |
46 | | - final_text_lines = self.split_long_lines(text_lines) |
47 | | - |
48 | | - self.fit_font_sizes(final_text_lines, author) |
49 | | - |
50 | | - self.draw_quote_text(final_text_lines) |
51 | | - self.draw_author_text(author) |
52 | | - |
53 | | - self.background_image.save('quote.png') |
54 | | - return 'quote.png' |
55 | | - |
56 | | - def split_text(self, content): |
57 | | - max_line_length = 70 |
58 | | - words = content.split() |
59 | | - current_line = "" |
60 | | - text_lines = [] |
61 | | - for word in words: |
62 | | - if len(current_line) + len(word) + 1 <= max_line_length: |
63 | | - current_line = current_line + " " + word if current_line else word |
64 | | - else: |
65 | | - text_lines.append(current_line) |
66 | | - current_line = word |
67 | | - if current_line: |
68 | | - text_lines.append(current_line) |
69 | | - return text_lines |
70 | | - |
71 | | - def split_long_lines(self, text_lines): |
72 | | - final_text_lines = [] |
73 | | - for line in text_lines: |
74 | | - if self.draw.textbbox((0, 0), line, font=self.quote_font)[2] > self.left_half_width: |
75 | | - final_text_lines.extend(self.split_line(line, self.quote_font, self.left_half_width)) |
76 | | - else: |
77 | | - final_text_lines.append(line) |
78 | | - return final_text_lines |
79 | | - |
80 | | - def get_text_height(self, font, lines): |
81 | | - total_height = 0 |
82 | | - for line in lines: |
83 | | - textbbox = self.draw.textbbox((0, 0), line, font=font) |
84 | | - total_height += textbbox[3] - textbbox[1] |
85 | | - return total_height |
86 | | - |
87 | | - def fit_font_size(self, font, text, max_height): |
88 | | - while self.draw.textbbox((0, 0), text, font=font)[3] > max_height and font.size > 8: |
89 | | - font.size -= 1 |
90 | | - |
91 | | - def fit_font_sizes(self, text_lines, author): |
92 | | - for line in text_lines: |
93 | | - self.fit_font_size(self.quote_font, line, self.max_text_height) |
94 | | - |
95 | | - while self.get_text_height(self.quote_font, text_lines) > self.max_text_height and self.quote_font.size > 4: |
96 | | - self.quote_font.size -= 2 |
97 | | - |
98 | | - while self.draw.textbbox((0, 0), author, font=self.author_font)[3] > self.background_image.height and self.author_font.size > 8: |
99 | | - self.author_font.size -= 1 |
100 | | - |
101 | | - def draw_quote_text(self, text_lines): |
102 | | - y = (self.background_image.height - self.get_text_height(self.quote_font, text_lines)) / 2 |
103 | | - for line in text_lines: |
104 | | - textbbox = self.draw.textbbox((0, 0), line, font=self.quote_font) |
105 | | - x = (self.left_half_width - textbbox[2]) / 2 |
106 | | - self.draw.text((x, y), line, fill='black', font=self.quote_font) |
107 | | - y += textbbox[3] - textbbox[1] |
108 | | - |
109 | | - def draw_author_text(self, author): |
110 | | - padding = 10 |
111 | | - author_bbox = self.draw.textbbox((0, 0), author, font=self.author_font) |
112 | | - x = padding |
113 | | - y = (self.background_image.height - author_bbox[3]) - padding |
114 | | - self.draw.text((x, y), author, fill='black', font=self.author_font) |
| 8 | +from classes.quote_image_creator import QuoteImageCreator |
115 | 9 |
|
116 | 10 | class SFun(commands.Cog): |
117 | 11 | """Fun""" |
|
0 commit comments