简体   繁体   中英

Kivy how to rotate a picture

我正在尝试旋转一些我必须在屏幕上显示的图片,这些图片在stacklayout内,我需要将它们显示为Portrait而不是landscape,我正在使用Image Widget Thanks

The previous 2 answer of toto_tico is a way to do, but i would rather create a new widget for it, and use it:

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()

Then, use this widget as other Image widget, you just have a "angle" property you can play with.

Note: the collision detection is not handled on the image, except in the scatter example. Scatter can be expensive just for rotate something, but at least the collision works.

I don't think the Scatter is meant to be use for this. But I guess is a more intuitive solution. The Scatter includes a rotation (and also a scale) property.

Basically, I embedded the Image inside a Scatter and use the rotation property to rotate 90 degrees.

Why do I say the Scatter is not meant for this task. Basically because it allows gestures over it. You can basically translate, rotate or scale with your fingers (or using the multi-touch mouse emulation ). That is why in the next example I am setting the do_scale , do_rotation and do_translation to false. I am clarifying this before you get confuse with the 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()

I think they are two ways of doing this. I'll post two answers and let others decide what is the right approach. I personally prefer this method because I think it's computational lighter. However, it is not that intuitive

This method uses a RelativeLayout and two context instructions (Rotate and Translate).

1 - You need to embed the Image inside the RelativeLayout . Why? Because the way Rotate works is similar to putting a nail in the (0,0) coordinate, ie bottom-left corner. The RelativeLayout sets the 0,0 to the position of the Widget.

2- You will need to use the canvas

3- As I said before, the Rotate instruction is equivalent to put a nail in the (0,0) coordinate. Think about a piece of paper. If you put a nail in the corner the rotation is going to end on the left. So, before the rotation, you need to Translate the piece of paper to your right.

4- Now you can Rotate the RelativeLayout and It will end in the position you are expecting.

There is another advantage of using a RelativeLayout. It already includes two important instructions ( PushMatrix and PopMatrix ) that you must understand if you are extensively working with rotating, scaling or translating.

Here is an example code:

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM