Проблема со смещением при повороте текста на изображении (Pillow)
main.py (здесь я рисую)
from Tool import Tool #методы рисования
from Canvas import Canvas #холст
from Object import Text #текстовый объект
p = Canvas((100, 100), Color.green) #базовый холст 100x100
#рисование текста
Tool.draw(
p.layers[0].draw, #базовый холст
Text('Sample <del color=red>text<del>', Text.Font(
'minecraft.ttf',
12,
)),
fg=Color.black,
rotate=100, #тут проблемы
)
p.show()
Tool.py (инструменты для рисования)
@staticmethod
def draw(
drawable: Object | Image.Image | Layer, #на чём мы рисуем объект (layer/canvas)
obj: Object, #наш текстовый объект
coords: Sequence[int] | int = None, #дефолт - (0, 0)
fg: Object | Color = None, #чёрный
rotate: int = 0, #100
...
):
if isinstance(drawable, ImageDraw.ImageDraw):
base_img = drawable.im
if not isinstance(base_img, Image.Image): base_img = Image.frombytes(base_img.mode, base_img.size, base_img.tobytes())
elif isinstance(drawable, Image.Image): base_img = drawable
elif hasattr(drawable, 'draw'): base_img = drawable.draw
w, h = (size, size) if isinstance(size, int) else (size or (0, 0))
SS = 4
# --- в целом, это тут не причём, но чтобы развеять туман ---
temp_img: Image.Image = Image.new("RGBA", (max(1, int(w * SS)), max(1, int(h * SS))), (0, 0, 0, 0)) #temp canvas
temp_draw: ImageDraw.ImageDraw = ImageDraw.Draw(temp_img)
# ---
...
elif isinstance(obj, Text):
if obj.font.file: font: FreeTypeFont = ImageFont.truetype(obj.font.file, obj.font.size)
else: font: FreeTypeFont = ImageFont.load_default(obj.font.size)
bbox = temp_draw.textbbox((0, 0), obj.content, font=font)
text_w, text_h = bbox[2] - bbox[0], bbox[3] - bbox[1]
temp_img = Image.new("RGBA", (max(1, int(text_w * SS)), max(1, int(text_h * SS))), (0, 0, 0, 0)) #text canvas
temp_draw = ImageDraw.Draw(temp_img)
temp_draw.text((0, 0), obj.content, fg, font)
if rotate != 0:
temp_img = temp_img.rotate(-rotate, expand=True, resample=Image.BICUBIC) #новый холст с повёрнутым текстом
b = temp_img.getbbox()
w, h = temp_img.size
print(w, h, b)
# --- ! ЧАСТЬ ДЛИ ФИКСА ! ---
if 0 <= rotate <= 90:
#тут всё работает идеально!
x0 = -b[0]
y0 = -b[1]
elif 90 < rotate <= 180:
#здесь я пытался что-то сделать, работая даже с h&w, но не получилось, заложил лишь основу
x0 = -b[0] - 0 #по сути, здесь всё работает правильно, но мне нужно вычесть какое-то число... вручную это делать нельзя (значение ставить, например: -80...)
y0 = -b[1]
elif 180 < rotate <= 270:
#не работает
x0 = -(w - b[2])
y0 = -(h - b[3])
elif 270 < rotate < 360:
#не работает
x0 = -b[0]
y0 = -(h - b[3])
else: #логично 0-90
x0 = -b[0]
y0 = -b[1]
...
#вставка холста с повернутым текстом на базовый холст
base_img.paste(temp_img, (int(x0), int(y0)), temp_img) #x0 и y0 координаты вставки, которые, как я думаю, нужно откорректировать
Я оставил только необходимую часть кода (некоторое может быть и не важно для кого-то, но кто его знает...).
Вкратце:
- Проблема со смещением текста при повороте.
- Когда текст вращается на 0-90° - всё хорошо, в остальных случаях текст куда-то смещается, даже выходит за границы изображения.
- Сам текст поворачивается правильно, проблема именно в неверном позиционировании текста (нужно наладить смещение).
Слева то, что необходимо, справа, то что сейчас