第5回 ビットマップを描画する


今回はビットマップの描画について説明します。
画面イメージの読み込みにはTranslation Kitというものが活躍してくれます。
BeOSが用意しているトランスレータというものがいかに強力な仕組みであるか、
今回のプログラムでわかると思います。

さて、今回のソース全体です。

// 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クラス自身の機能として

などがあります。画面に描画するのは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を使ってビットマップを読み込んでいれば、
将来、未知の画像フォーマットに対してもトランスレータをインストールすれば、
アプリケーションとしては、その画像を取り扱うことができます。

補足 2000/07/28


「BTranslationUtils::GetBitmap()関数に渡す引数はフルパスの方がいいのではないか?」
という指摘を村本さんからいただきました。
それは確かにそうなのですが、今回の主題はTranslation Kitなのであえて端折りました。

フルパスを指定しないとTerminalから正常にファイルの取得が出来ない状況(シンボリックリンクとか駆使して)が
あったと思うのですが、今回調べて見たら再現できませんでした。
知っているよというかた、メールください。

ちなみに、わかっている人向けに説明すると、自分のentry_refを取得するには、

app_info info;   
entry_ref my_path;  // 自分のパスへのentry_ref
be_app->GetAppinfo(&info);
my_path = info.ref; 

といった感じです。

[<<前へ] [次へ>>] [戻る]

big56 big56@anet.ne.jp
低金利でお得なローン探し 給料前でお金がない・・ そろそろ結婚適齢期???
[PR] | ヒーリング会社案内 作成se 転職川口栃木荻窪池袋中国SEO対策消費者金融車 買取テンプレート沖縄旅行免許合宿二輪引越しプレゼントゴルフ会員権留学レーシックマッサージFXアフィリエイトFXホームページ制作デイトレードハワイ旅行タイバンコクハワイ レンタカーベスト ハワイ ホテル レーツバリ島Hawaii hotelsHawaii Activitiesbhhrハワイホテルテキスト広告
【運営会社「パラダイムシフト」サービス】 ハワイ現地オプショナルツアーリラックマ) - ビジネスクラス航空券 - 格安航空券(1) - 格安航空券(2) - 海外ホテル - 韓国旅行 - タイムシェア - ホテル 予約
無料ホームページ - 携帯ホームページ - 無料ホームページ作成 - レンタルサーバー - ブログ - ヴィラ - ハワイ コンドミニアム - バリ島 ホテル - プーケット ホテル - 旅行 口コミ - 旅行情報 - 国際電話 - ホノルルマラソン - 掲示板監視 - 風評被害 - ホテル比較 - ノースウェスト航空 - ファイナルチェッカー