Проблема со смещением при повороте текста на изображении (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° - всё хорошо, в остальных случаях текст куда-то смещается, даже выходит за границы изображения.
  • Сам текст поворачивается правильно, проблема именно в неверном позиционировании текста (нужно наладить смещение).

Слева то, что необходимо, справа, то что сейчас

пример


Ответы (0 шт):