Skip to content

Commit 5087cbf

Browse files
authored
[Leveler] Fix dep warnings on PIL 9.2 or greater (#177)
1 parent 0ba5f86 commit 5087cbf

File tree

4 files changed

+61
-33
lines changed

4 files changed

+61
-33
lines changed

leveler/def_imgen_utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"Installing-Leveler#my-bot-throws-error-on-load-something-related-to-pillow."
2020
)
2121

22+
try:
23+
from PIL.Image.Resampling import LANCZOS
24+
except ModuleNotFoundError:
25+
from PIL.Image import LANCZOS
2226

2327
try:
2428
import numpy
@@ -104,7 +108,7 @@ def _humanize_number(self, number):
104108
# finds the the pixel to center the text
105109
def _center(self, start, end, text, font):
106110
dist = end - start
107-
width = font.getsize(text)[0]
111+
width = self._get_character_pixel_width(font, text)
108112
start_pos = start + ((dist - width) / 2)
109113
return int(start_pos)
110114

@@ -150,7 +154,7 @@ def _add_corners(self, im, rad, multiplier=6):
150154
circle = Image.new("L", (raw_length, raw_length), 0)
151155
draw = ImageDraw.Draw(circle)
152156
draw.ellipse((0, 0, raw_length, raw_length), fill=255)
153-
circle = circle.resize((rad * 2, rad * 2), Image.ANTIALIAS)
157+
circle = circle.resize((rad * 2, rad * 2), LANCZOS)
154158

155159
alpha = Image.new("L", im.size, 255)
156160
w, h = im.size

leveler/image_generators.py

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
"Installing-Leveler#my-bot-throws-error-on-load-something-related-to-pillow."
2424
)
2525

26+
try:
27+
from PIL.Image.Resampling import LANCZOS
28+
except ModuleNotFoundError:
29+
from PIL.Image import LANCZOS
30+
2631

2732
log = getLogger("red.fixator10-cogs.leveler")
2833

@@ -76,10 +81,10 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
7681
# if char.isalnum() or char in string.punctuation or char in string.whitespace:
7782
if self.char_in_font(char, check_font):
7883
draw.text((write_pos, y), "{}".format(char), font=font, fill=fill)
79-
write_pos += font.getsize(char)[0]
84+
write_pos += self._get_character_pixel_width(font, char)
8085
else:
8186
draw.text((write_pos, y), "{}".format(char), font=unicode_font, fill=fill)
82-
write_pos += unicode_font.getsize(char)[0]
87+
write_pos += self._get_character_pixel_width(unicode_font, char)
8388
check_font.close()
8489

8590
# set canvas
@@ -96,7 +101,7 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
96101
info_section_process = Image.new("RGBA", (bg_width, height), bg_color)
97102
# puts in background
98103
temp = bg_image
99-
bg_image = bg_image.resize((width, height), Image.ANTIALIAS)
104+
bg_image = bg_image.resize((width, height), LANCZOS)
100105
temp.close()
101106
temp = bg_image
102107
bg_image = bg_image.crop((0, 0, width, height))
@@ -151,9 +156,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
151156
draw_lvl_circle.ellipse([0, 0, raw_length, raw_length], fill=(250, 250, 250, 250))
152157
# put on profile circle background
153158
temp = lvl_circle
154-
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
159+
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
155160
temp.close()
156-
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
161+
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
157162
process.paste(lvl_circle, (circle_left, circle_top), lvl_bar_mask)
158163
lvl_bar_mask.close()
159164

@@ -165,13 +170,13 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
165170
# put in profile picture
166171
output = ImageOps.fit(profile_image, (raw_length, raw_length), centering=(0.5, 0.5))
167172
temp = output
168-
output.resize((profile_size, profile_size), Image.ANTIALIAS)
173+
output.resize((profile_size, profile_size), LANCZOS)
169174
temp.close()
170175
temp = mask
171-
mask = mask.resize((profile_size, profile_size), Image.ANTIALIAS)
176+
mask = mask.resize((profile_size, profile_size), LANCZOS)
172177
temp.close()
173178
temp = profile_image
174-
profile_image = profile_image.resize((profile_size, profile_size), Image.ANTIALIAS)
179+
profile_image = profile_image.resize((profile_size, profile_size), LANCZOS)
175180
temp.close()
176181
process.paste(profile_image, (circle_left + border, circle_top + border), mask)
177182

@@ -310,7 +315,7 @@ def make_levelup_image(
310315

311316
# puts in background
312317
temp = bg_image
313-
bg_image = bg_image.resize((width, height), Image.ANTIALIAS)
318+
bg_image = bg_image.resize((width, height), LANCZOS)
314319
temp.close()
315320
temp = bg_image
316321
bg_image = bg_image.crop((0, 0, width, height))
@@ -358,9 +363,9 @@ def make_levelup_image(
358363
draw_lvl_circle = ImageDraw.Draw(lvl_circle)
359364
draw_lvl_circle.ellipse([0, 0, raw_length, raw_length], fill=(250, 250, 250, 180))
360365
temp = lvl_circle
361-
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
366+
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
362367
temp.close()
363-
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
368+
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
364369
process.paste(lvl_circle, (circle_left, circle_top), lvl_bar_mask)
365370
lvl_bar_mask.close()
366371

@@ -369,13 +374,13 @@ def make_levelup_image(
369374
# put in profile picture
370375
output = ImageOps.fit(profile_image, (raw_length, raw_length), centering=(0.5, 0.5))
371376
temp = output
372-
output.resize((profile_size, profile_size), Image.ANTIALIAS)
377+
output.resize((profile_size, profile_size), LANCZOS)
373378
temp.close()
374379
temp = mask
375-
mask = mask.resize((profile_size, profile_size), Image.ANTIALIAS)
380+
mask = mask.resize((profile_size, profile_size), LANCZOS)
376381
temp.close()
377382
temp = profile_image
378-
profile_image = profile_image.resize((profile_size, profile_size), Image.ANTIALIAS)
383+
profile_image = profile_image.resize((profile_size, profile_size), LANCZOS)
379384
temp.close()
380385
process.paste(profile_image, (circle_left + border, circle_top + border), mask)
381386

@@ -449,10 +454,10 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
449454
# if char.isalnum() or char in string.punctuation or char in string.whitespace:
450455
if self.char_in_font(char, check_font):
451456
draw.text((write_pos, y), "{}".format(char), font=font, fill=fill)
452-
write_pos += font.getsize(char)[0]
457+
write_pos += self._get_character_pixel_width(font, char)
453458
else:
454459
draw.text((write_pos, y), "{}".format(char), font=unicode_font, fill=fill)
455-
write_pos += unicode_font.getsize(char)[0]
460+
write_pos += self._get_character_pixel_width(unicode_font, char)
456461
check_font.close()
457462

458463
# COLORS
@@ -499,7 +504,7 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
499504

500505
# puts in background
501506
temp = bg_image
502-
bg_image = bg_image.resize((340, 340), Image.ANTIALIAS)
507+
bg_image = bg_image.resize((340, 340), LANCZOS)
503508
temp.close()
504509
temp = bg_image
505510
bg_image = bg_image.crop((0, 0, 340, 305))
@@ -532,9 +537,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
532537
)
533538
# put border
534539
temp = lvl_circle
535-
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
540+
lvl_circle = lvl_circle.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
536541
temp.close()
537-
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), Image.ANTIALIAS)
542+
lvl_bar_mask = mask.resize((lvl_circle_dia, lvl_circle_dia), LANCZOS)
538543
process.paste(lvl_circle, (circle_left, circle_top), lvl_bar_mask)
539544
lvl_bar_mask.close()
540545

@@ -543,10 +548,10 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
543548
border = int(total_gap / 2)
544549
profile_size = lvl_circle_dia - total_gap
545550
temp = mask
546-
mask = mask.resize((profile_size, profile_size), Image.ANTIALIAS)
551+
mask = mask.resize((profile_size, profile_size), LANCZOS)
547552
temp.close()
548553
temp = profile_image
549-
profile_image = profile_image.resize((profile_size, profile_size), Image.ANTIALIAS)
554+
profile_image = profile_image.resize((profile_size, profile_size), LANCZOS)
550555
temp.close()
551556
process.paste(profile_image, (circle_left + border, circle_top + border), mask)
552557

@@ -731,7 +736,7 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
731736
badge_image = badge_image_original.convert("RGBA")
732737
badges_images[num].close()
733738
badge_image_original.close()
734-
badge_image_resized = badge_image.resize((raw_length, raw_length), Image.ANTIALIAS)
739+
badge_image_resized = badge_image.resize((raw_length, raw_length), LANCZOS)
735740
badge_image.close()
736741

737742
# structured like this because if border = 0, still leaves outline.
@@ -740,9 +745,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
740745
# put border on ellipse/circle
741746
output = ImageOps.fit(square, (raw_length, raw_length), centering=(0.5, 0.5))
742747
temp = output
743-
output = output.resize((size, size), Image.ANTIALIAS)
748+
output = output.resize((size, size), LANCZOS)
744749
temp.close()
745-
outer_mask = mask.resize((size, size), Image.ANTIALIAS)
750+
outer_mask = mask.resize((size, size), LANCZOS)
746751
process.paste(output, coord, outer_mask)
747752
outer_mask.close()
748753

@@ -753,9 +758,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
753758
centering=(0.5, 0.5),
754759
)
755760
temp = output
756-
output = output.resize((size - total_gap, size - total_gap), Image.ANTIALIAS)
761+
output = output.resize((size - total_gap, size - total_gap), LANCZOS)
757762
temp.close()
758-
inner_mask = mask.resize((size - total_gap, size - total_gap), Image.ANTIALIAS)
763+
inner_mask = mask.resize((size - total_gap, size - total_gap), LANCZOS)
759764
process.paste(
760765
output,
761766
(coord[0] + border_width, coord[1] + border_width),
@@ -771,9 +776,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
771776
centering=(0.5, 0.5),
772777
)
773778
temp = output
774-
output = output.resize((size, size), Image.ANTIALIAS)
779+
output = output.resize((size, size), LANCZOS)
775780
temp.close()
776-
outer_mask = mask.resize((size, size), Image.ANTIALIAS)
781+
outer_mask = mask.resize((size, size), LANCZOS)
777782
process.paste(output, coord, outer_mask)
778783
outer_mask.close()
779784
badge_image_resized.close()
@@ -808,9 +813,9 @@ def _write_unicode(text, init_x, y, font, unicode_font, fill):
808813
# put border on ellipse/circle
809814
output = ImageOps.fit(plus_square, (raw_length, raw_length), centering=(0.5, 0.5))
810815
temp = output
811-
output = output.resize((size, size), Image.ANTIALIAS)
816+
output = output.resize((size, size), LANCZOS)
812817
temp.close()
813-
outer_mask = mask.resize((size, size), Image.ANTIALIAS)
818+
outer_mask = mask.resize((size, size), LANCZOS)
814819
process.paste(output, coord, outer_mask)
815820
outer_mask.close()
816821
plus_square.close()

leveler/leveler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Leveler(
2929
):
3030
"""A level up thing with image generation!"""
3131

32-
__version__ = "3.0.4"
32+
__version__ = "3.0.5"
3333

3434
# noinspection PyMissingConstructor
3535
def __init__(self, bot: Red):

leveler/utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99

1010
from .abc import MixinMeta
1111

12+
try:
13+
from PIL import ImageFont
14+
except Exception as e:
15+
raise CogLoadError(
16+
f"Can't load pillow: {e}\n"
17+
"Please follow next steps on wiki: "
18+
"https://github.com/fixator10/Fixator10-Cogs/wiki/"
19+
"Installing-Leveler#my-bot-throws-error-on-load-something-related-to-pillow."
20+
)
21+
1222

1323
class Utils(MixinMeta):
1424
"""Utility methods"""
@@ -84,3 +94,12 @@ def _truncate_text(self, text, max_length):
8494
if len(text) > max_length:
8595
return text[: max_length - 1] + "…"
8696
return text
97+
98+
@staticmethod
99+
def _get_character_pixel_width(font: ImageFont.FreeTypeFont, char: str) -> int:
100+
"""Use getlength over using getsize for character pixel width, if available in PIL."""
101+
try:
102+
write_pos = int(font.getlength(char))
103+
except AttributeError:
104+
write_pos = font.getsize(char)[0]
105+
return write_pos

0 commit comments

Comments
 (0)