====== FBOを使う ====== FBOとは Frame Buffer Object の略で、通常画面に描画するものを一旦こちらのバッファに貯め込むこと、いいことがあるよ、という機能です。Frameとは、動画における1枚を指す言葉です。Bufferはなにか主たる処理をするために必要な一時記憶領域。Objectはモノをさし、描画した内容を1枚の画像として保存しておくことができます。具体的には. * 描画している任意の部分を画像に保存したい。 * 描画しているある部分を切り出したい。 * 描画している内容を好きな位置に好きな大きさで描きたい といったことが可能になります。では具体的にやってみましょう。 ===== 描画している任意の部分を画像に保存したい ===== 例えば画面上にある画像を表示し、その上に任意の文字列を表示したサンプルがあるとします。画像自体はofImageで読み込みしているので、保存することは簡単にできますが、その上に描画されている任意テキストも一緒に、となるとちょっと難しくなります。例えばofに ofSaveScreen()なる関数が用意されているので、これを使えば画面にスクリーンショットを保存できますし、mac標準のスクリーンショット機能を使えば同様のことは可能です。一方で任意の場所に関して保存したい場合はfboが役に立ちます。以下のサンプルは画面上に sample.jpg を表示し、その上に "Hello ofFbo"が表示されています。これをsample.jpgのサイズでテキスト込で保存し直す場合のサンプルです。sample.jpg も合わせてここにリンクおきます。 * {{ :openframeworks:sample.jpg?linkonly |}} 適当なプロジェクトを作成して、下記のofApp.h, ofApp.cpp を置き換えてください。 #pragma once #include "ofMain.h" class ofApp : public ofBaseApp{ public: void setup(); void update(); void draw(); void keyPressed(int key); ofImage img; ofFbo fbo; }; #include "ofApp.h" void ofApp::setup(){ // sample.jpg を読み込む dataフォルダにおいておくことを忘れずに img.load(ofToDataPath("sample.jpg")); // 読み込んだ画像サイズ分のfboサイズをメモリ確保する fbo.allocate(img.getWidth(), img.getHeight()); } void ofApp::update(){ // fbo.begin()からfbo.end()の間に記述された描画内容がfboに保存される fbo.begin(); ofClear(0); img.draw(0,0); ofDrawBitmapStringHighlight("Hello Fbo", 20,20); fbo.end(); } void ofApp::draw(){ ofBackground(0); // 0,0の位置にオリジナルのサイズでfboを描画する。 // update()内で描画した内容が表示される。 fbo.draw(0,0); } void ofApp::keyPressed(int key){ if( key == 's' ){ ofPixels p; fbo.readToPixels(p); // saved_image.jpgというjpgファイルを最高品質で補zんする ofSaveImage(p, ofToDataPath("saved_image.jpg"), OF_IMAGE_QUALITY_BEST); // データフォルダをfinderで開く(terminalで open ./data を実行している) ofSystem("open "+ofToDataPath("")); } } 以上を実行し、キーボードの 's' キーを押すと、saved_image.jpg が保存されたディレクトリがfinderで開きます。saved_image.jpgを確認すると、Hello Fboがsample.jpg上に記載された画像になっているのが確認できます。