さて、今回のソース全体です。
// sample04.cpp
#include <Application.h> // BApplicationを使うために必要
#include <Window.h> // BWindowを使うために必要
#include <View.h> // BViewを使うために必要
#include <Bitmap.h> // BBitmapを使うために必要
#include <TranslationUtils.h> // BTranslationUtilsを使うために必要
// クラスの前方宣言
class MyApp;
class MyWindow;
class MyView;
class MyApp : public BApplication
{
public:
MyApp();
private:
MyWindow* m_win;
};
class MyWindow : public BWindow
{
public:
MyWindow(BRect frame,const char* title,window_type type,uint32 flags);
virtual bool QuitRequested(); // 終了が要求されたときに呼ばれる関数
private:
MyView* m_view;
};
class MyView : public BView
{
public:
MyView(BRect frame,const char *name,uint32 resizingMode,uint32 flags);
~MyView();
virtual void Draw(BRect updateRect); // 再描画要求の時に呼ばれる関数
private:
BBitmap* m_bitmap;
};
MyApp::MyApp()
:BApplication("application/x-vnd.big56-MyApp")
{
m_win = new MyWindow(BRect(100,100,575,308),"ビットマップ描画テスト",B_TITLED_WINDOW,0);
m_win->Show();
}
MyWindow::MyWindow(BRect frame,const char* title,window_type type,uint32 flags)
:BWindow(frame,title,type,flags)
{
frame.OffsetTo(0,0); // 与えられたBRectの左上が(0,0)になるようにする
m_view = new MyView(frame,"theView",B_FOLLOW_ALL_SIDES,B_WILL_DRAW);
AddChild(m_view);
}
bool MyWindow::QuitRequested()
{
// アプリケーションを終了する
be_app-gt;PostMessage(B_QUIT_REQUESTED);
return true;
}
MyView::MyView(BRect frame,const char* title,uint32 resizingMode,uint32 flags)
:BView(frame,title,resizingMode,flags)
{
m_bitmap = BTranslationUtils::GetBitmap("belogo.jpg"); // ビットマップを読み込む
}
MyView::~MyView()
{
delete m_bitmap;
}
void MyView::Draw(BRect updateRect)
{
if (m_bitmap !=NULL) DrawBitmap(m_bitmap,BPoint(0,0));
}
int main(int argc,char** argv)
{
MyApp app;
app.Run();
return 0;
}
今回のプログラムの圧縮ファイル source05.zip
結果は次のようになります。
画像ファイルは/boot/documentation/graphics/以下にあるものを使用しました。
今回は書き足した行がほとんどないので、ソースを見ただけでもある程度のことはわかると思います。
まずは、ビットマップの読み込みから解説します。
ビットマップはMyViewのコンストラクタ内で読み込んでいます。
MyView::MyView(BRect frame,const char* title,uint32 resizingMode,uint32 flags)
:BView(frame,title,resizingMode,flags)
{
m_bitmap = BTranslationUtils::GetBitmap("belogo.jpg"); // ビットマップを読み込む
}
BTranslationUtilsはビットマップを読み込むための関数群がまとめられたクラスです。
この中のGetBitmap()という関数を使ってビットマップを読み込んでいます。
GetBitmap()関数はBBitmapという、ビットマップを表現するためのクラスのインスタンスを返します。
もし、ファイル名が無効だったり、ビットマップイメージを保持していないファイルを指定するとNULLを返します。
まず、この関数のすごいところは、トランスレーターさえインストールされていれば、
どんなフォーマットの画像形式でも読み込んでしまうところにあります。
BeOS R5にはデフォルトでTIFF,TGA,PPM,PNG,JPEG,BMPのイメージのトランスレータが用意されていますが
一般的によく使われる(と筆者が思う)PNG,JPEG,BMPが同じコードで読み込めてしまうだけでもすごいと思います。
またこの関数により得られる恩恵として、フォーマットが違う画像形式に対して
共通のインターフェースでアクセスできるというものがあります。
BBitmapクラス自身の機能として
ビットマップを表示しているのは、再描画要求に応答するMyView::Draw()関数内で行っています。
void MyView::Draw(BRect updateRect)
{
if (m_bitmap !=NULL) DrawBitmap(m_bitmap,BPoint(0,0));
}
読み込んだビットマップが有効かどうかエラーチェックしてから、描画をしています。
このコードではビューのx座標が0、y座標が0の点をビットマップを描き始める場所に指定しています。
DrawBitmap()関数にはいくつか別の引数のバージョンがあるのでそれを解説しましょう。
void DrawBitmap(const BBitmap *image)
void DrawBitmap(const BBitmap *image, BPoint point)
void DrawBitmap(const BBitmap *image, BRect destination)
void DrawBitmap(const BBitmap *image, BRect source, BRect destination)
imageには描画するBBitmapのインスタンスへのポインタを指定します。
ほかに何も指定しない場合は、現在のペンの位置(前回紹介したMovePenTo()で指定する)が
ビットマップの左上の点になります。
BPoint(座標)で指定するときは、描くビットマップの左上の点を指定します。
BRect(矩形)を指定すると、ビットマップが指定された矩形の形に拡大縮小されて描画されます。
BRectを二つ指定するバージョンでは、ビットマップの一部分が描画されることになります。
第2引数で、ビットマップのどの部分を描画するかを指定して、
第3引数で、ビューのどの部分に描画するかを指定します。
先程のバージョンと同じように、矩形の大きさが違う場合は拡大縮小されて描画されます。
ビットマップを描画するだけなら以上の説明で充分ですが、
BTranslationUtils::GetBitmap関数で読み込んだBBitmapのインスタンスは
アプリケーションで解放する必要があります。
これをMyViewのデストラクタで処理しています。
MyView::~MyView()
{
delete m_bitmap;
}
これをしないとメモリリークの元になるので、注意してください。
今回はビットマップの描画をしましたが、BeOSのトランスレータの仕組みがいかに強力か
わかっていただけたでしょうか?
Translation Kitを使ってビットマップを読み込んでいれば、
将来、未知の画像フォーマットに対してもトランスレータをインストールすれば、
アプリケーションとしては、その画像を取り扱うことができます。
フルパスを指定しないとTerminalから正常にファイルの取得が出来ない状況(シンボリックリンクとか駆使して)が
あったと思うのですが、今回調べて見たら再現できませんでした。
知っているよというかた、メールください。
ちなみに、わかっている人向けに説明すると、自分のentry_refを取得するには、
app_info info; entry_ref my_path; // 自分のパスへのentry_ref be_app->GetAppinfo(&info); my_path = info.ref;
といった感じです。
|
|||
|
|