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。
Kivy の Widget には、export_to_png() というメソッドがあって、ソレを使えば pngファイルとしてWidget内の様子を画像保存できる模様。
動作確認環境は、Windows10 x64 1903 + Python 2.7.17 32bit + Kivy 1.11.1。
◎ 動作確認。 :
以下のように表示されるスクリプトを書いて動作確認。
ソースは以下。
_02_canvas2.py
Save をクリックして保存された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ファイルは以下。
ちゃんと保存されてるっぽい。
◎ 課題。 :
canvasサイズを指定することはできるのだろうか…。例えば、512x512、1024x1024、2048x2048等に決め打ちできれば、画像生成をするためのツールなども作れそうだけど…。
ウインドウサイズを変更すると canvasサイズも変わってしまってゴミが見えてしまうのだけど。texture に図形を描画することができれば、Image に texture を指定することでそういう問題は起きないはず。ただ、texture に図形描画をする方法が分からない。Kivy でそんなことはできるのだろうか…。
ウインドウサイズを変更すると canvasサイズも変わってしまってゴミが見えてしまうのだけど。texture に図形を描画することができれば、Image に texture を指定することでそういう問題は起きないはず。ただ、texture に図形描画をする方法が分からない。Kivy でそんなことはできるのだろうか…。
[ ツッコむ ]
以上です。