ホーム > デベロッパ > SophiaFramework > BREW C++ 逆引きコード集

BREW C++ プログラミング 逆引きコード集 : 画像・描画

C++ で作成されたBREW アプリで、画像を扱う処理や、画像の描画を行う方法です。
SophiaFramework を用いています。

描画できない

描画できない場合は以下の項目を確認してください。

・GUI フレームワークを使用したアプリ (アプリクラスが SFYApplication を継承) の場合

1. 描画ハンドラの中で描画していますか?

2. 描画ハンドラマクロの引数の graphics を使って描画していますか?

// 描画ハンドラの定義(ウィンドウ内に描画)
XANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderRequest, invoker, reason, graphics)
{
    unused(invoker);
    unused(reason);

    // 四角形を描画する
    graphics->DrawRectangle(SFXRectangle(10, 10, 25, 25));
    
    // graphics->Update(); は必要なし
}

3. コンストラクタ内で描画ハンドラを登録していますか?

// コンストラクタ
MyWindow::MyWindow(Void) : ...
{
    // ハンドラを登録する(エラー処理は省略)
   RegisterHandler(
            SFXEventRange(SFEVT_RESPONDER_RENDER, SFEVT_RESPONDER_RENDER,
                                        SFP16_RENDER_REQUEST, SFP16_RENDER_REQUEST),
            XANDLER_INTERNAL(OnRenderRequest));

    return;
}

・GUI フレームワークを使用しないアプリ (アプリクラスが SFCApplication を継承) の場合

1. グラフィックス・インターフェースを取得していますか?

SFXGraphicsPtr graphics;

// グラフィックス・インターフェースを取得する
graphics = SFXGraphics::GetInstance();

// 四角形を描画する
graphics->DrawRectangle(SFXRectangle(10, 10, 25, 25));

2. SFXGraphics::Update 関数を呼び出していますか?

graphics->Update();

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照: リファレンス 3.1. SFY アプレット | リファレンス 5.5. カスタマイズ

      

SFXFrameColor クラスを使ってフレームを描画する

SFXFrameColor クラスは、フレームの枠と影の部分の色をまとめて管理するためのクラスです。

このクラスは SFXGraphics クラスでフレームを描画する場合に利用します。フレームの各部分の色について演算したり、フレーム全体について色演算できます。

※ 数値がオーバーフローする場合や、アンダーフローする場合は適切に処理されます。

SFXFrameColor クラスの使用方法
Void SFXColorExplainer::_SFXFrameColor(Void) const
{
    // フレーム色定数を準備する
    // ( 以下のフレーム色は、緑色の枠と赤色の影を表す )

    static SFXFrameColor::AtomRecConst frame = {
        {0x00, 0x00, 0xFF, 0x00}, {0x00, 0xFF, 0x00, 0x00}
    };
    SFXGraphicsPtr graphics;

    // グラフィック オブジェクトを取得する

    graphics = SFXGraphics::GetInstance();
    if (graphics != null) {

        // フレームを描画する
        // ( フレームは指定した矩形の外側に描画される )

        graphics->DrawFrame(SFXRectangle(20, 20, 40, 40), frame);

        // 画面をアップデートする

        graphics->Update();
    }
    return;
}
      

SFXBevelColor クラスを使ってべベル矩形を描画する

SFXBevelColor クラスは、ベベル矩形のライト・ベース・ダークの各部分の色をまとめて管理するためのクラスです。( 「ベベル矩形」とは立体的に見える長方形のことです。 )

このクラスは SFXGraphics クラスでベベル矩形を描画する場合に利用します。ベベル矩形の各部分の色について演算したり、全体について色演算できます。

※ 数値がオーバーフローする場合や、アンダーフローする場合は適切に処理されます。

SFXBevelColor クラスの使用方法
Void SFXColorExplainer::_SFXBevelColor(Void) const
{
    // 青色のベース色定数を準備する

    static SFXRGBColor::AtomRecConst color = {
        0x00, 0x88, 0x88, 0xFF
    };
    SFXRGBColor temp;
    SFXBevelColor bevel;
    SFXGraphicsPtr graphics;

    // べベル色のライト部分・ベース部分・ダーク部分を青色に設定する

    bevel.Set(color, color, color);

    // ライト部分の各要素に 0x66 を加算する

    bevel.AddLightRGB(0x66);

    // ダーク部分の各要素から 0x44 を減算する

    bevel.SubDarkRGB(0x44);

    // グラフィック オブジェクトを取得する

    graphics = SFXGraphics::GetInstance();
    if (graphics != null) {

        // べベル矩形を描画する

        graphics->FillBevelRectangle(SFXRectangle(20, 20, 40, 40), bevel);

        // べベル色のライト部分とダーク部分を入れ替える

        temp = bevel.GetLight();
        bevel.SetLight(bevel.GetDark());
        bevel.SetDark(temp);

        // べベル矩形を描画する

        graphics->FillBevelRectangle(SFXRectangle(24, 24, 32, 32), bevel);

        // 画面をアップデートする

        graphics->Update();
    }
    return;
}
      

ウィンドウ内を再描画するには

ウィンドウ内を再描画するには、SFRResponder::InvalidateContent 関数を使用します。

SFRWindowPtr window;

// window は再描画したいウィンドウ

window->InvalidateContent();

この関数が呼び出されると、自動的に描画ハンドラが呼び出されます。

SFRResponder::InvalidateContent の引数に、再描画したい領域を指定することもできます。

参照 SFRResponder::InvalidateContent

      

ウィンドウ上に画像を描画するには

ウィンドウ上に画像を描画するには、ウィンドウに描画ハンドラを登録し、
描画ハンドラ内のグラフィック・オブジェクトを使って描画します。

// ウィンドウの定義
class MyWindow : public SFRTitleWindow {
    ...
    MyWindow(Void);

    // 描画ハンドラの宣言
    HANDLER_DECLARE_VOIDRENDER(MyWindow, OnRenderContent)
};

// 描画ハンドラの定義
HANDLER_IMPLEMENT_VOIDRENDER(MyWindow, OnRenderContent, graphics)
{
    // SFBBitmapSmp 型の bitmap に画像が格納されているとする

    // SFXRectangle(0, 0, 100, 100) に画像を描画する
    graphics->BitBlt(SFXRectangle(0, 0, 100, 100), bitmap);

    return;
}

// コンストラクタ
MyWindow::MyWindow(Void) : ...
{
    // ハンドラを登録する(エラー処理は省略)
    RegisterHandler(SREVT_RESPONDER_RENDER, SRP16_RENDER_CONTENT,
                        HANDLER_BEFORE, HANDLER_FUNCTION(OnRenderContent));
    return;
}

graphics インスタンスについては グラフィックインターフェースの取得 を参照

      

画像のサイズを取得する

画像のサイズを取得するには、SFBBitmap::GetInfo 関数、または、SFBImage::GetInfo 関数を使用します。

SFBBitmap の場合

// SFBBitmapSmp 型の bitmap に画像が格納されているとする

AEEBitmapInfo info = {0};
bitmap->GetInfo(&info);
SInt16 width = info.cx;   // 画像の幅
SInt16 height = info.cy;  // 画像の高さ

SFBImage の場合

// SFBImageSmp 型の image に画像が格納されているとする

AEEImageInfo info = {0};
image->GetInfo(&info);
SInt16 width = info.cx;   // 画像の幅
SInt16 height = info.cy;  // 画像の高さ

参照 SFBBitmap::GetInfo | SFBImage::GetInfo

      

画像を描画する

画像を描画するには、SFXGraphics::BitBlt 関数、または、SFBImage::Draw 関数を使用します。

SFBBitmap の場合

// SFBBitmapSmp 型の bitmap に画像が格納されているとする

// SFXRectangle(0, 0, 100, 100) に画像を描画する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
graphics->BitBlt(SFXRectangle(0, 0, 100, 100), bitmap);

SFBImage の場合

// SFBImageSmp 型の image に画像が格納されているとする

// 画像の左上端が (10, 20) となるように描画する
image->Draw(SFXGrid(10, 20)); 

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::BitBlt | SFXGraphics::GetInstance |
SFBImage::Draw

      

画像をファイルから読み込む

画像をファイルから読み込むには、SFBShell::LoadBitmap または SFBShell::LoadImage 関数を使用します。

SFBBitmap を用いる場合

SFBBitmapSmp bitmap(SFBShell::GetInstance()->LoadBitmap("picture.bmp"));

SFBImage を用いる場合(JPEG 画像など)

SFBImageSmp image(SFBShell::GetInstance()->LoadImage("picture.jpg"));

参照 SFBShell::LoadBitmap | SFBShell::LoadImage | SFBShell::GetInstance

      

画像をリソースから読み込む

画像をリソースから読み込むには、SFBShell::LoadResBitmap 関数を使用します。

// 画像をリソースから読み込む
// APPNAME_RES_FILE は リソースエディタで作成したファイル名、
// BITMAP_RES_NAME は リソースエディタで設定したリソースの ID
SFBBitmapSmp bitmap(SFBShell::GetInstance()->LoadResBitmap(
    APPNAME_RES_FILE, BITMAP_RES_NAME));

SFBBitmapSmp 型の(スマート)ポインタ bitmap を用いて画像を操作します。

参照 SFBShell::LoadResBitmap | SFBShell::GetInstance

      

複数行描画の際の文字列の高さを取得

SFXGraphics::DrawString 関数で複数行描画する際に、必要な文字列の高さを取得するには、
SFXGraphics::MeasureString 関数を使用します。

// 幅を 100 としたときの描画に必要な高さ
SInt16 height = SFXGraphics::MeasureString(AEE_FONT_NORMAL,
    "very long long long long text", 100);

参照 SFXGraphics::DrawString | SFXGraphics::MeasureString

      

複数行の文字列の描画

複数行の文字列を描画するには、SFXGraphics::DrawString 関数を使用します。

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// 左上が (20, 20), 幅 100, 高さ 100 の長方形内に複数行で描画する
graphics->DrawString("very long long long long text",
                     SFXRectangle(20, 20, 100, 100));

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::DrawString | SFXGraphics::GetInstance

      

文字列を描画する

文字列を描画するには、SFXGraphics::DrawText 関数、または
SFXGraphics::DrawString 関数を使用します。

SFXGraphics::DrawText は1行、SFXGraphics::DrawString は複数行の描画を行います。

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// "Hello World" 文字列を座標 (10, 20) に描画する
graphics->DrawText("Hello World", SFXGrid(10, 20));

// 左上が (20, 20), 幅 100, 高さ 100 の長方形内に複数行で描画する
graphics->DrawString("very long long long long text",
                     SFXRectangle(20, 20, 100, 100));

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::DrawText | SFXGraphics::DrawString |
SFXGraphics::GetInstance

      

文字列の幅を取得

文字列の幅を取得するには、SFXGraphics::MeasureText 関数を使用します。

// 文字列 "abcd" の幅を取得する
SInt16 width = SFXGraphics::MeasureText(AEE_FONT_NORMAL, "abcd");

SInt16 fit;

// 文字列 "abcd" の幅を取得。最大幅を30 とする
// widthLimit には幅30に入りきる最大の文字列の幅が入る
// fit には最大の文字列の文字数が入る
SInt16 widthLimit = SFXGraphics::MeasureText(AEE_FONT_NORMAL, "abcd", 30, &fit);

グラフィック・オブジェクトを用いる場合

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
SInt16 width = graphics->MeasureText("abcd");

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::MeasureText | SFXGraphics::GetInstance

      

文字列の高さを取得

文字列の高さを取得するには、SFXGraphics::GetFontHeight 関数を使用します。

SInt16 height = SFXGraphics::GetFontHeight(AEE_FONT_NORMAL);

グラフィック・オブジェクトを用いる場合

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
SInt16 height = graphics->GetFontHeight();

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::GetFontHeight | SFXGraphics::GetInstance

      

効率の良い定数構造体の渡し方

関数の引数に定数の構造体を渡す場合(例えば、SFXGraphics::SetForeColor 関数などに
SFXRGBColor クラスのインスタンスを渡す場合)、以下のように記述できます。

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

graphics->SetForeColor(SFXRGBColor(0xFF, 0x00, 0x00, 0x00));

この方法では、SFXRGBColor クラスのコンストラクタの分がオーバーヘッドになります。
SFXRGBColor クラスのコンストラクタを起動させずに、
定数を直接渡すには以下のように記述します。

static SFXRGBColor::AtomRecConst color = {
    0x00, 0xFF, 0x00, 0x00    // 左から順に α、R、G、B
};
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

graphics->SetForeColor(color);

このような構造体として、カラーの他にシェイプ クラスなどがあります。

参照 SFXGraphics::GetInstance | SFXGraphics::SetForeColor |
SFXRGBColor::AtomRecConst

      

画面の最下部に文字を表示する領域を作る

画面の最下部に文字を表示する領域を作り、そこに文字を表示するには、
SFXRectangle クラスを利用し、次のようにします。

// グラフィックス インターフェイスを取得する
SFXGraphicsPtr graphics = SFXGraphics::GetInstance();

// ディスプレイ領域を取得する
SFXRectangleConst devRect(graphics->GetDeviceRectangle());

// 文字列表示領域
SFXRectangle textRect(devRect);

// 文字列表示領域の高さをフォントの高さに設定する
textRect.SetHeight(graphics->GetFontHeight());

// 文字列表示領域の下端をディスプレイ領域の下端に設定する
textRect.SnapBottom(devRect.GetBottom());

// 文字列の表示
graphics->DrawText(SFXWideString("表示文字列"), textRect,
                  IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE | IDF_RECT_FILL);

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::GetInstance | SFXGraphics::GetDeviceRectangle |
SFXGraphics::GetFontHeight | SFXGraphics::DrawText |
SFXRectangle::GetBottom | SFXRectangle::SetHeight |
SFXRectangle::SnapBottom

      

長方形を描画する

長方形を描画するには、SFXRectangle クラスと SFXGraphics クラスを使用します。
画面やウインドウへの描画は、描画ハンドラの中で行います。

// 長方形の作成
SFXRectangle rect(10, 10, 20, 10);   // x 座標, y 座標, 横幅, 高さ

// 色の設定
SFXRGBColor color(0x00, 0x00, 0xFF, 0x00);  // 赤, 緑, 青, アルファ

SFXGraphicsPtr graphics = SFXGraphics::GetInstance();
graphics->DrawRectangle(rect, color);     // 長方形の描画
graphics->FillRectangle(rect, color);     // 長方形の塗りつぶし

graphics インスタンスについては グラフィックインターフェースの取得 を参照

参照 SFXGraphics::GetInstance | SFXGraphics::DrawRectangle |
SFXGraphics::FillRectangle

      

画面のサイズを取得する

画面のサイズを取得するには、SFXGraphics::GetDeviceRectangle 関数、または
SFXGraphics::GetDeviceSize 関数を使用します。

// 画面サイズが 横 240、縦 290 の場合

SFXRectangle rect = SFXGraphics::GetDeviceRectangle();
// rect は (x, y) = (0, 0), 幅 240, 高さ 290 となる

SFXSize size = SFXGraphics::GetDeviceSize();
// size は 幅 240, 高さ 290 となる

参照 SFXGraphics::GetDeviceRectangle | SFXGraphics::GetDeviceSize

      

リソースから読み込んだビットマップをコピーする

リソースから読み込んだビットマップをコピーするには、
SFBBitmap::CreateCompatibleBitmap 関数でグラフィックインターフェイス互換の
ビットマップを作成した後、SFBBitmap::BltIn 関数を使用します。

// SFBBitmapSmp 型の変数 src にリソースから読み込んだビットマップ(コピー元)が
// 格納されているとする

// 元ビットマップの大きさを取得する
AEEBitmapInfo bmpinfo;
src->GetInfo(&bmpinfo);

SFBBitmapSmp disp(SFXGraphics::GetInstance()->GetDestination());
SFBBitmapSmp dest; // コピー先のビットマップ

// グラフィックインターフェイス互換のビットマップを作成する
if (disp->CreateCompatibleBitmap(&dest, static_cast<UInt16>(bmpinfo.cx),
        static_cast<UInt16>(bmpinfo.cy)) == SFERR_NO_ERROR) {

    // 画像を転送する
    dest->BltIn(SFXRectangle(0, 0, static_cast<SInt16>(bmpinfo.cx),
        static_cast<SInt16>(bmpinfo.cy)), src, SFXGrid(0, 0));
}

参照 SFXGraphics::GetDestination | SFBBitmap::CreateCompatibleBitmap |
SFBBitmap::BltIn

      

矩形の辺同士をくっつける

矩形の辺同士をくっつけるには、SFXRectangle::SnapRight
SFXRectangle::SetRight 関数を使用します。

SFXRectangle one;
SFXRectangle two;

// two の左辺に one の右辺が接合するように矩形を移動する
one.SnapRight(two.GetLeft());

// two の左辺に one の右辺を接合する
one.SetRight(two.GetLeft());

参照 SFXRectangle::SnapRight | SFXRectangle::SetRight