Kivy как повернуть изображение

Я пытаюсь повернуть некоторые фотографии, которые я должен показать на экране, эти изображения находятся внутри stacklayout, и мне нужно показать их как портрет, а не пейзаж, я использую виджет изображения Спасибо

3 ответов


предыдущий ответ 2 toto_tico-это способ сделать, но я бы предпочел создать для него новый виджет и использовать его:

Builder.load_string('''
<RotatedImage>:
    canvas.before:
        PushMatrix
        Rotate:
            angle: root.angle
            axis: 0, 0, 1
            origin: root.center
    canvas.after:
        PopMatrix
''')

class RotatedImage(Image):
    angle = NumericProperty()

затем используйте этот виджет в качестве другого виджета изображения, у вас просто есть свойство "угол", с которым вы можете играть.

Примечание: обнаружение столкновений не обрабатывается на изображении, за исключением примера разброса. Разброс может быть дорогим только для поворота чего-то, но, по крайней мере, столкновение работает.


Я не думаю, что скаттер предназначен для использования для этого. Но я думаю, это более интуитивное решение. Разброс включает в себя свойство вращения (а также масштаб).

в основном, я встроил изображение внутри разброса и использую свойство вращения для поворота на 90 градусов.

почему я говорю скаттер не предназначен для этой задачи. В основном потому, что он позволяет жесты над ним. Вы можете в основном переводить, вращать или масштабировать пальцами (или с помощью эмуляция мыши мультитач). Вот почему в следующем примере я устанавливаю do_scale, do_rotation и do_translation значение false. Я разъясняю это, прежде чем вы путаете с do_rotation: false

from kivy.app import App
from kivy.uix.stacklayout import StackLayout
from kivy.lang import Builder

Builder.load_string("""
<Example>:
    Image:
        source: 'kivy.png'
        size_hint: None,None
        size: 64,64
    Scatter:
        pos: 0,0
        size_hint: None,None
        size: 64,64
        do_rotation: False
        do_scale: False
        do_translation: False
        rotation: 90
        Image:
            source: 'kivy.png'
            size_hint: None,None
            size: 64,64

""")

class Example(App, StackLayout):
    def build(self):
        return self

if __name__ == "__main__":
    Example().run()

Я думаю, что это два способа сделать это. Я опубликую два ответа, и пусть другие решат, какой правильный подход. Я лично предпочитаю этот метод, потому что я думаю, что он вычислительный легче. Однако это не то, что интуитивно

этот метод использует RelativeLayout и две контекстные инструкции (Rotate и Translate).

1-вам нужно вставить изображение внутри RelativeLayout. Почему? Потому что способ повернуть работает аналогично положить гвоздь в координата (0,0), т. е. нижний левый угол. The RelativeLayout устанавливает 0,0 в положение виджета.

2-Вам нужно будет использовать холст

3 - Как я уже говорил, инструкция Rotate эквивалентна установке гвоздя в координату (0,0). Подумайте о клочке бумаги. Если вы положите гвоздь в угол, вращение закончится слева. Итак, перед ротацией вам нужно перевести бумажки ваше право.

4 - Теперь вы можете поворот RelativeLayout, и он закончится в положении, которое вы ожидаете.

есть еще одно преимущество использования RelativeLayout. Он уже включает в себя две важные инструкции (PushMatrix и PopMatrix), что вы должны понимать, если вы активно работаете с вращением, масштабированием или переводом.

вот пример кода:

from kivy.app import App
from kivy.uix.stacklayout import StackLayout
from kivy.lang import Builder

Builder.load_string("""
<Example>:
    Image:
        source: 'kivy.png'
        size_hint: None,None
        size: 64,64
    RelativeLayout
        size_hint: None,None
        size: 64,64
        canvas.before:
            Translate:
                x: 64
            Rotate:
                angle: 90
                axis: 0,0,1
        Image:
            source: 'kivy.png'
            size_hint: None,None
            size: 64,64
""")

class Example(App, StackLayout):
    def build(self):
        return self

if __name__ == "__main__":
    Example().run()