mieki256's diary



2019/11/02() [n年前の日記]

#1 [kivy][python] Kivyのcanvasに描画した図形をファイル保存

Kivy の canvas に描画した図形を画像ファイルとして保存できるかどうか調べたり。

Kivy の Widget には、export_to_png() というメソッドがあって、ソレを使えば pngファイルとしてWidget内の様子を画像保存できる模様。

動作確認環境は、Windows10 x64 1903 + Python 2.7.17 32bit + Kivy 1.11.1。

動作確認。 :

以下のように表示されるスクリプトを書いて動作確認。

02_canvas2.ss01.png

  • Drawをクリックすると図形を描画。
  • Save をクリックすると、output.png という画像ファイル名で見た目を保存。

ソースは以下。

_02_canvas2.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.graphics import Ellipse
from kivy.graphics import Line
from kivy.graphics import Rectangle
from kivy.graphics import Color
from kivy.graphics import Translate
from kivy.graphics.texture import Texture
from kivy.properties import ObjectProperty
from kivy.lang import Builder

from kivy.config import Config
Config.set('graphics', 'width', '512')
Config.set('graphics', 'height', '512')

output_filename = "./output.png"

# my.kv
Builder.load_string('''
#:kivy 1.11.1
<MyWidget>:
    BoxLayout:
        size: root.size
        orientation: "vertical"

        MyPaintImage:
            id: myimage
            texture: self.texture_image
            size_hint_y: 0.9

            canvas.before:
                Color:
                    rgba: 0, 0, 0, 1
                Rectangle:
                    pos: self.pos
                    size: self.size

        BoxLayout:
            size_hint_y: 0.1

            Button:
                id: btn_draw
                text: "Draw"
                on_press: myimage.draw_shapes()

            Button:
                id: btn_save
                text: "Save"
                on_press: myimage.save_canvas_image()
''')


class MyPaintImage(Image):
    texture_image = ObjectProperty(None)

    def __init__(self, **kwargs):
        super(MyPaintImage, self).__init__(**kwargs)
        self.texture_image = Texture.create(size=self.size)

    def draw_shapes(self):
        bx, by = self.pos
        with self.canvas:
            Translate(bx, by)

            Color(0.1, 0.4, 0.1)
            Rectangle(pos=(0, 0), size=self.size)

            Color(0, 0.75, 0)
            Rectangle(pos=(16, 64), size=(300, 200))

            poslist = [
                32, 32,
                480, 420,
                480, 32,
            ]
            Color(1, 0, 0, .3)
            Line(points=poslist, width=6, close='True')

            Color(0, .5, 1, 0.5)
            Ellipse(pos=(76, 50), size=(360, 360))

            Translate(-bx, -by)

    def save_canvas_image(self):
        self.export_to_png(filename=output_filename, scale=1.0)
        print("save %s" % output_filename)


class MyWidget(Widget):
    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)


class MyApp(App):
    def __init__(self, **kwargs):
        super(MyApp, self).__init__(**kwargs)
        self.title = 'Simple Graphics Test 2'

    def build(self):
        return MyWidget()


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

  • 今回は、.kv ファイルを .py の中に含めて記述してみた。Builder.load_string(''' ... ''') の中に、.kv の内容が記述されている。
  • .kv の中で、自作クラスを記述することもできるらしい。今回、MyPaintImage を作っているけれど、そのクラス名も記述できている。
  • draw_shapes() が、canvas に図形を描画している部分。
  • save_canvas_image() が、その Widget の見た目を画像保存してる部分。
  • draw_shapes() の中で Translate(x, y) が呼ばれているけど、これをしておかないと、その Widget の位置ではなく、ウインドウ全体の位置で描画されてしまう。図形を描画し終わったら、元の位置に戻すための Translate(x, y) を呼ぶ。

Save をクリックして保存されたpngファイルは以下。

output.png

ちゃんと保存されてるっぽい。

課題。 :

canvasサイズを指定することはできるのだろうか…。例えば、512x512、1024x1024、2048x2048等に決め打ちできれば、画像生成をするためのツールなども作れそうだけど…。

ウインドウサイズを変更すると canvasサイズも変わってしまってゴミが見えてしまうのだけど。texture に図形を描画することができれば、Image に texture を指定することでそういう問題は起きないはず。ただ、texture に図形描画をする方法が分からない。Kivy でそんなことはできるのだろうか…。

以上です。

過去ログ表示

Prev - 2019/11 - Next
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project