画像を触れるようになるとイロイロと出来る事が増えそうな気がしますね。
結果を目で見れるし俄然やる気も出るというもの。
モノクロに出来たり、モザイクを掛けてみたり...
ま、その前に基本から。
←こんな赤い画像を青くしたい!
という訳で、フォームにTImageを貼り付けて、実行用に読み込みボタンと変換ボタンを作ります。
<Unit1.h>
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TImage *Image1;
TButton *LoadBtn;
TButton *ConvertBtn;
void __fastcall LoadBtnClick(TObject *Sender);
void __fastcall ConvertBtnClick(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
<Unit1.cpp>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::LoadBtnClick(TObject *Sender)
{
// ビットマップを読み込んで表示
Image1->Picture->LoadFromFile("red.bmp");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ConvertBtnClick(TObject *Sender)
{
// TBitmapオブジェクトを作成
Graphics::TBitmap *BM = new Graphics::TBitmap;
// 24bitのビットマップを改めて読み込み
BM->LoadFromFile("red.bmp");
// 画像を1pixelずつ走査していきます
for( int y=0; y<BM->Height; y++ ){
// ScanLineで1行分まとめて取得
Byte *Line = (Byte*)BM->ScanLine[y];
int i=0;
for( int x=0; x<BM->Width; x++ ){
Line[i] = 0xFF; // B
Line[i+1] = 0; // G
Line[i+2] = 0; // Rの順に入ってます
i+=3;
}
}
Image1->Picture->Assign(BM); // Image1にコピー
delete BM; // オブジェクト解放
}
//---------------------------------------------------------------------------
TImageに画像を表示させるだけならLoadFromFileを使えば簡単です。
Stretchプロパティをtrueにすれば、TImageのサイズに応じて画像を引き伸ばしてくれます。
さぁ、Graphics::TBitmapですが、コイツを使いこなせる事が出来れば
画像処理はずいぶんと分かるようになります。
まずは、TBitmapオブジェクトを作成してから、変換したい画像をLoadFromFileで読み込みます。
次に出てくるScanLine[]は、画像の横1行分をまとめて取ってきます。
正確には先頭のポインタなんですが、24bitビットマップの場合
青→緑→赤、青→緑→赤、とBGR要素が8bitずつ順番に配列の中に入ってるわけです。
つまり、ScanLineで取得した配列の長さは ( 画像の幅 * 3 ) になるというわけ。
今回は赤い画像を読み込みましたが、強引に青(B)要素を255にして
赤(R)要素を0としたので赤から青に変換できちゃったわけです。
ScanLineはポインタで取得するので、読み込みも書き込みも直接出来て便利です。