Start_python’s diary

ふたり暮らし

アラフィフ夫婦のフリーランスプラン

Kivy 写真の向きを正しく表示する(Python Kivyの取説・使い方 第10回)

写真の向きを正しく表示する方法

今回はPILモジュールを使って「画像を回転」してKivyで表示していきます。

画面のスライドのときに使った「Imageウィジェット」では、ファイル名を指定して画像を表示するため画像ファイルを編集する場合は一度保存する必要があります。

出来れば画像ファイルはそのまま残したいので今回は「Textureウィジェット」を使ってcanvas内に表示させたいと思います。

 

まずはそのまま画像を表示してみます。ここで少し苦労しました。

プログラムのコード

# フル画面を解除
from kivy.config import Config
Config.set('graphics', 'fullscreen', 0)

from PIL import Image

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle

from kivy.core.window import Window


class MainApp(App):
    def build(self):
        self.title = 'テスト'

        layout = Widget()
        layout.size=Window.size

        image = Image.open('./image/IMG_0.jpg')
        
        texture = Texture.create(size=image.size) 
        texture.blit_buffer(image.tobytes())
        texture.flip_vertical()
        with layout.canvas.before:
            layout.rect = Rectangle(texture=texture ,pos=layout.pos, size=layout.size)
            
        return layout


if __name__ == '__main__':
    MainApp().run()

 

解説

layout.size=Window.size

この一行がなかなか見つけられませんでした。「layout = Widget()」でレイアウトを作っただけではウィンドウの大きさに関係なくレイアウトの大きさが「100×100」になって画像が左下に小さく表示されるだけでした。

f:id:Start_python:20191220112153p:plain

kvファイルでは「size: root.size」でいいのですが、rootがどうしていいかわからず「from kivy.core.window import Window」で「Window.size」を取得することにしました。おそらくこれが正解ではないと思います。(ウィンドウサイズを変更しても画像サイズはそのままです)

texture.flip_vertical()

画像を上下反転させます。PILでは左上が座標(0, 0)に対しKivyでは左下が座標(0, 0)になるためです。

layout.rect = Rectangle(texture=texture ,pos=layout.pos, size=layout.size)

長方形をレイアウトサイズで作りその中にテクスチャ画像を貼り付けます。

 

今度は写真(画像)を回転させてみます。

プログラムのコード

# フル画面を解除して画面の幅と高さを設定
from kivy.config import Config
Config.set('graphics', 'fullscreen', 0)
Config.set('graphics', 'width', 320)
Config.set('graphics', 'height', 568)
Config.set('graphics', 'resizable', 0)

from PIL import Image
from PIL.ExifTags import TAGS

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics.texture import Texture
from kivy.graphics import Rectangle

from kivy.core.window import Window


class MainApp(App):
    def build(self):
        self.title = 'テスト'

        layout = Widget()
        layout.size=Window.size

        image = Image.open('./image/IMG_0.jpg')

        exif = image._getexif()

        #exif情報からOrientationを取得
        exif_data = []
        for id, value in exif.items():
            if TAGS.get(id) == 'Orientation':
                tag = TAGS.get(id, id),value
                exif_data.extend(tag)

        if exif_data[1] == 3:
            #180度回転
            image = image.transpose(Image.ROTATE_180)
        elif exif_data[1] == 6:
            #270度回転
            image = image.transpose(Image.ROTATE_270)
        elif exif_data[1] == 8:
            #90度回転
            image = image.transpose(Image.ROTATE_90)

        texture = Texture.create(size=image.size) 
        texture.blit_buffer(image.tobytes())
        texture.flip_vertical()
        with layout.canvas.before:
            layout.rect = Rectangle(texture=texture ,pos=layout.pos, size=layout.size)
            
        return layout


if __name__ == '__main__':
    MainApp().run()

 

f:id:Start_python:20191220115746p:plain

縦横の比率など気になるところはありますが、向きが正常に戻せたのでこれで良しとします。

これを画面のスライドで利用することも(あーやってこーやれば)出来そうです。

 

まとめ

まだまだKivyについては勉強不足です。レイアウトやkvファイルの有り無しなど少しの違いで苦労することが多かったです。日本語での解説サイトがまだまだ少ないので調べるにも時間がかかりました。

 

次回はKivyでグラフを表示させてみたいと思います。

 

 

保存ファイル

lesson65.py

lesson66.py

 

 

文責:Luke