質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

562閲覧

KivyのFBOを使う事でのフレームバッファー

kevin.c.michael

総合スコア27

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/12/02 08:59

こんにちは、KivyのFBO(Framebuffer)についてです。
このFBOを利用する事で、フレームバッファ機能を作れるとのことですが、
実際どのように作成するのかわかりません。

私の目標はiOSのナビゲーションバーで使われている、ブラー効果を作る事です。
わたしの考えでは、表示した画面の一部をFBOでフレームバッファーとして再利用し、effectモジュールでブラー効果をつければ出来るのではと考えています。

ですが、その足がかりとなりそうなFBOがよくわからないのです。
下記のようなコードを書きました。

(...Pythonファイルの方は本家サイトのリファレンスそのままです。...)

私の気がかりな部分は

self.fbo = Fbo(size=(256, 256))

with self.fbo:

の二つです。
とりあえずself.fboがカンバスと同じ用量なのは理解しました。
ただ、Fbo関数がなんのためにあって、何をする関数なのかがわかりません。

もしkivyの言うフレームバッファというものが、Rectangleなどを使っての図形描画でしか表示することができないのであれば私の目標は達せないことになります。

###この、Fbo関数が何かを教えて下さい。
###もしわかれば、iOSブラーをどう作るかを教えて下さい。

python

1from kivy.app import App 2from kivy.lang import Builder 3from kivy.core.window import Window 4from kivy.graphics import Fbo, Color, Rectangle 5from kivy.uix.widget import Widget 6 7 8Window.clearcolor = (1, 1, 1, 1) 9 10class FboTest(Widget): 11 def __init__(self, **kwargs): 12 super(FboTest, self).__init__(**kwargs) 13 14 # first step is to create the fbo and use the fbo texture on other 15 # rectangle 16 17 with self.canvas: 18 # create the fbo 19 self.fbo = Fbo(size=(256, 256)) 20 21 # show our fbo on the widget in different size 22 Color(1, 1, 1, 1) 23 Rectangle(size=(500, 500), texture=self.fbo.texture) 24 25 # in the second step, you can draw whatever you want on the fbo 26 with self.fbo: 27 28 Color(0, 0, 1, 1) 29 Rectangle(size=(256, 64)) 30 Color(0, 1, 0, 1) 31 Rectangle(size=(256, 64), pos=(0, 64)) 32 33 34class FboApp(App): 35 36 def build(self): 37 pass 38 39if __name__ == '__main__': 40 FboApp().run()

kv

1#kvfile 2#ファイル名は fbo.kv 3 4ScreenManager: 5 sca: sca 6 Screen: 7 id: sca 8 name: "ScreenA" 9 ScrollView: 10 size_hint_y: 1 11 pos_hint: {'top': 1} 12 GridLayout: 13 cols: 1 14 size_hint: 1, None 15 height: self.minimum_height 16 padding: 0, sp(50), 0, sp(50) 17 FboTest: 18 transitions: transitions 19 Label: 20 id: transitions 21 text: "Pellentesque" 22 font_size: 150 23 text_size: self.width, None 24 size_hint: 1, None 25 height: self.texture_size[1] 26 color: 0.000 ,0.4784 ,1.000, 1 27 28 RelativeLayout: 29 size_hint: 1, None 30 height: sp(100) 31 canvas.before: 32 Color: 33 rgba: 1,1,1,.8 34 Rectangle: 35 size: self.size 36 pos: self.pos

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

この、Fbo関数が何かを教えて下さい。

その関数を呼び出すことでフレームバッファを作ってます。
「with self.canvas:」内で呼ぶことに違和感があるかもしれませんが、個人的にはそうすることでself.canvasと同じ形式(色深度やピッチとか色々)のフレームバッファを作っていると思ってます。

もしわかれば、iOSブラーをどう作るかを教えて下さい。

EffectWidgetが使えるかと。

python3

1from kivy.app import runTouchApp 2from kivy.lang import Builder 3 4 5root = Builder.load_string(r''' 6#:import ew kivy.uix.effectwidget 7<Label>: 8 font_size: 50 9 bold: True 10 canvas.before: 11 Color: 12 rgb: 0, 0, 0, 13 Rectangle: 14 pos: self.pos 15 size: self.size 16 17BoxLayout: 18 orientation: 'vertical' 19 Label: 20 text: 'NoEffect' 21 EffectWidget: 22 effects: [ew.PixelateEffect(), ] 23 Label: 24 text: 'Pixelate' 25 EffectWidget: 26 effects: [ew.HorizontalBlurEffect(size=30.0), ] 27 Label: 28 text: 'HorizontalBlur' 29 EffectWidget: 30 effects: [ew.VerticalBlurEffect(size=30.0), ] 31 Label: 32 text: 'VerticalBlur' 33 EffectWidget: 34 effects: [ew.VerticalBlurEffect(size=30.0), ew.HorizontalBlurEffect(size=30.0), ] 35 Label: 36 text: 'VerticalBlur + HorizontalBlur' 37''') 38 39runTouchApp(root) 40

screenshot

もし希望のEffectが無い場合は自分で作る事になると思います。ソースコードを見る限りはGLSLを書かないといけないようなので難易度は高そうですが。

投稿2017/12/02 12:43

編集2017/12/03 14:34
gottadiveintopy

総合スコア736

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kevin.c.michael

2017/12/02 13:21

ありがとうございます^^ すいません、EffectWidgetについては知っていました。 例えば、iOSのようにウィジェットの背景をブラーする場合はどういった工夫を講じれば良いのか、もしわかれば教えて下さい。
kevin.c.michael

2017/12/02 13:24

ちなみにそのEffectwidgetですが、特定の範囲内のみをBlurするなどはできますか? self.widgetやidsなどから取得したウィジェットからではなく、例えばcollidepointをうまく工夫して座標を取得し、その部分のみにEffectwidgetを当てるような?
gottadiveintopy

2017/12/02 13:26

希望のEffectが無いのならやっぱり自分でEffectBaseを継承したclassを作ってGLSL葬るしかないんじゃないかと、ちょっと他の方法は今の所思いつかないですね。
kevin.c.michael

2017/12/02 13:29

gottadiveintopyさん、ありがとうございます。 やはりがんばって実装しなきゃダメみたいですねGLSLでなんとか^^; あと、趣旨違いですがkivyユーザーってどのくらいなんですかね?
gottadiveintopy

2017/12/02 16:10 編集

> ちなみにそのEffectwidgetですが、特定の範囲内のみをBlurするなどはできますか? ドキュメントを読む限りEffectWidget自体にはそのような機能はなさそうです。GLSLにできるのかまではわからなないですが。 > self.widgetやidsなどから取得したウィジェットからではなく、例えばcollidepointをうまく工夫して座標を取得し、その部分のみにEffectwidgetを当てるような? EffectWidgetは自分の子にしかEffectをかけれないので、ぼかしたい部分を参照するImageウィジットをEffectWidgetの子にしてやればできそうです。 私はiOS持ってなくでkevinさんの求める物の細かい部分がわからないのですが、 ぼかす前の背景はどのぐらいの頻度で変わりますか?又ぼかす位置はリアルタイムで変わりますか? 背景の変更頻度が少ないなら背景全体をぼかしたTextureを非GLSLでもいいので作っておけばEffectWidgetを使わずともやりたい事は実現できると思いますよ。
kevin.c.michael

2017/12/03 06:14

gottadiveintopyさん ありがとうございます! ボカシ位置についてですが、すりガラスのようなイメージです。 下記にイメージの参考になりそうな動画のURLを添付しておきます。 この動画投稿者の方はkivyで実装しているようです。 https://www.youtube.com/watch?v=KwIRVxVITEw この方のやっていることと同じことをやりたいのです。 この方は別なkivyuserが制作したウィジェッとにマスクをかけるコードを利用して、ブラーを実現しているようです。 そのコード自体にはGLSLでマスク効果を実現してるっぽいのです。 >> 背景の変更頻度が少ないなら背景全体をぼかしたTextureを非GLSLでもいいので作っておけばEffectWidgetを使わずともやりたい事は実現できると思いますよ。 ですよね^^; 私もGLSL使わない線で考えてみたものがあります。 要素を画像化し、それにブラー効果をかけてスクロールした時に同じスクロール量で移動させると言うものでした。 しかし、これにはkivyで撮影した際、画面内(ウィンドウ内)のスクリーンショットのみしか取れず、その描画領域全体を撮影することは困難でした。 自分はこんな感じしか考えつきませんでした。 もし、gottadiveintopyさんが別にアイデアがあれば少し伺う事は可能ですか?
kevin.c.michael

2017/12/03 06:16

gottadiveintopyさん >> EffectWidgetは自分の子にしかEffectをかけれないので、ぼかしたい部分を参照するImageウィジットをEffectWidgetの子にしてやればできそうです。 すいません、できればこの部分などももう少しお聞かせいただきたいので、合わせてコメントお願いできますか?
gottadiveintopy

2017/12/03 14:11

> すいません、できればこの部分などももう少しお聞かせいただきたいので、合わせてコメントお願いできますか? 背景のTextureが取得できるのなら 部分Texture = 背景のTexture.get_region(...) image = Image(texture=部分Texture) effectwidget.add_widget(image) みたいにできるかと思ったのですが、やりたいことは動画のようなScrollViewの一部にBlurをかけることだったんですね。だったらやっぱりScrollViewをEffectWidgetの子にしてEffectかけてやるのが最適なような気がします。私自身はGLSLを扱った事が無いためあくまで予想ですが。 > これにはkivyで撮影した際、画面内(ウィンドウ内)のスクリーンショットのみしか取れず、その描画領域全体を撮影することは困難でした。 撮影がどんな方法かわかりませんが、ScrollViewは自身の大きさで描画を切り抜いてしまうのでScrollViewの子から直接描画結果をもらえば切り抜かれる前の物が得られますよ。やり方はWidgetクラスのexport_to_png()のソースコードが参考になるかと。ただいずれにしてもGLSLを用いたものよりプログラムが複雑になりそうな気がします。
kevin.c.michael

2017/12/03 14:20

gottadiveintopyさん ありがとうございます。 今まで色々試してみましたが、EffectWidgetのBlur系を直に使用しようとしたらまったくうまくいきませんでした。 gottadiveintopyさんの言うようにやはり、GLSLしかないのかなと踏んでます。 なんとか早めに習得して早めに作っていきます。 また、コメントを残そうと思います。
gottadiveintopy

2017/12/03 14:40 編集

あまり力になれずごめんなさい。 私の載せたSampleコードですが、Labelの背景を塗ってなかったためにEffectの範囲が文字の部分に限定されて正しいEffectの効果の確認ができていなかったので、修正しました。少しだけiOSのもに近づいたと思います。
kevin.c.michael

2017/12/03 15:09

ご協力に感謝します。 ありがとうございます。
kevin.c.michael

2017/12/03 15:13 編集

すいません、ついでに教えていただければ幸いなのですが、 FBO関数はフレームバッファーを作ることでしたよね。 例えば他のクラスのウィジェットをフレームバッファとしてもってくることは可能ですか? フレームバッファ自体がcanvasのような特性があるならば、あるウィジェットの背景にcanvasとして他クラスのウィジェットをFBOとして持ってこれないかと思っているのですが?
gottadiveintopy

2017/12/04 01:47

それが正にexport_to_png()が内部で行っている事なので、ソースコードを読む事をお薦めします。 短いコードなのですぐに解ると思いますよ :-)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問