C++Builder は、様々なフォーマットの画像を扱うのも簡単だ。……が、まとまった情報が見つからなくて苦労したので、ここにまとめておく。動作確認は C++Builder XE3。
例として、JPEG 画像を背景画像として、その上に、BMP 画像と透過 PNG 画像を重ねる。合成結果を PNG 画像として保存する。
準備として、ビットマップ形式以外の画像ファイルを読み書きしたい場合は、対応するヘッダをインクルードしておく。
ヘッダをインクルードしてしまえば、読み込みに関しては、画像フォーマットを気にせずに読み込めるようになる。書き込みは、対応する画像形式を扱うクラスに任せる。コードは以下。
結果は右の画像のようになる。
シンプルなコードだが、透過もきちんと自動処理されている。
ポイントは、TImage を使うこと(ここでは動的生成しているが、もちろんフォームに貼り付けても良い)。TImage のローダーは、画像形式に関わらず読み込める。TBitmap を使うと PNG を読み込めなかった。
古いバージョンの C++Builder/Delphi だと、PNG の読み込みには TPngImage で画像の読み込みを行わなければならなかったようだが、現在は、TImage を使えば良い。
逆に、書き込みは、明示的に TPngImage を使っている。
のように拡張子で自動的に PNG に変換してくれるかなーと期待したが、そんなことは無かった。
例として、JPEG 画像を背景画像として、その上に、BMP 画像と透過 PNG 画像を重ねる。合成結果を PNG 画像として保存する。
背景 JPEG | BMP | 透過 PNG |
---|---|---|
※Web 用に PNG に変換してあるが、元は BMP |
準備として、ビットマップ形式以外の画像ファイルを読み書きしたい場合は、対応するヘッダをインクルードしておく。
#include <Jpeg.hpp>
#include <PNGImage.hpp>
ヘッダをインクルードしてしまえば、読み込みに関しては、画像フォーマットを気にせずに読み込めるようになる。書き込みは、対応する画像形式を扱うクラスに任せる。コードは以下。
void __fastcall TFormTest01::Button1Click(TObject *Sender)
{
unique_ptr<TImage> aImageMerge(new TImage(this));
unique_ptr<TImage> aImageBG(new TImage(this));
unique_ptr<TImage> aImage1(new TImage(this));
unique_ptr<TImage> aImage2(new TImage(this));
unique_ptr<TPngImage> aPng(new TPngImage());
// 画像ロード
aImageBG->AutoSize = true;
aImageBG->Picture->LoadFromFile(L"R:\\TestBG.jpg"); // JPEG
aImage1->AutoSize = true;
aImage1->Picture->LoadFromFile(L"R:\\Test1.bmp"); // BMP
aImage2->AutoSize = true;
aImage2->Picture->LoadFromFile(L"R:\\Test2.png"); // PNG
// 合成画像のサイズを背景画像に合わせる
aImageMerge->Width = aImageBG->Width;
aImageMerge->Height = aImageBG->Height;
// 合成
aImageMerge->Canvas->Draw(0, 0, aImageBG->Picture->Graphic);
aImageMerge->Canvas->Draw(100, 200, aImage1->Picture->Graphic);
aImageMerge->Canvas->Draw(300, 200, aImage2->Picture->Graphic);
// PNG 保存
aPng->Assign(aImageMerge->Picture->Graphic);
aPng->SaveToFile(L"R:\\Result.png");
}
結果は右の画像のようになる。
シンプルなコードだが、透過もきちんと自動処理されている。
ポイントは、TImage を使うこと(ここでは動的生成しているが、もちろんフォームに貼り付けても良い)。TImage のローダーは、画像形式に関わらず読み込める。TBitmap を使うと PNG を読み込めなかった。
古いバージョンの C++Builder/Delphi だと、PNG の読み込みには TPngImage で画像の読み込みを行わなければならなかったようだが、現在は、TImage を使えば良い。
逆に、書き込みは、明示的に TPngImage を使っている。
aImageBG->Picture->SaveToFile(L"R:\\Result.png");
のように拡張子で自動的に PNG に変換してくれるかなーと期待したが、そんなことは無かった。