若我們想要圖形由右下朝左上移動,如上圖,水平x減少80個畫素,垂直y減少80個畫素,這樣就可以做到由右下朝左上移動。
好了,知道原理後該如何做?我希望在我們的實驗室中,按下move按鈕,圖形會朝左上移動,按下back按鈕,圖形會跑回來,如下圖。
那我們必須在move按鈕的按下事件中,寫右下朝左上移動,然後在back按鈕的按下事件中,寫左上朝右下移動。
觀察上圖,我們要移動綠色框所圈起來的畫素,那我們要知道綠色框的左上角點與圖紙的原點(左上角) 偏移多少畫素,綠色框的寬與高是多少畫素,然後每個畫素x-80,y-80,把它寫回圖紙物件 myLab (TBitmap物件),再把 myLab 指給Image1物件,這樣就會顯示移動的樣子了。
上述說明可以知道,為了移動這些像素,我們要知道好多參數,
綠色框偏移值
綠色框的寬與高
要移動多少畫素
...
int ori_w; //原圖寬
int ori_h; //原圖高
int off_x; //矩形對原點偏移x(左上點)
int off_y; //矩形對原點偏移y
int box_w; //框寬度限制
int box_h; //框高度限制
int mov_x; //tar x 矩形移動到(左上點)
int mov_y; //tar y
我不想直接在按鈕的事件中撰寫代碼,這會使程式看起來凌亂,我想要在事件中只寫參數,然後把參數傳遞給我們的LIB去處理,我們可以使用結構體來簡化參數的傳遞,也就是我只需傳遞結構體的指標就可以了。做法如下,
1.在 mylib.h中宣告結構體
struct coordinate{ //參數結構體宣告
int ori_w; //原圖寬
int ori_h; //原圖高
int off_x; //矩形對原點偏移x(左上點)
int off_y; //矩形對原點偏移y
int box_w; //框寬度限制
int box_h; //框高度限制
int mov_x; //tar x 矩形移動到(左上點)
int mov_y; //tar y
};
2.順便宣告結構體指標
coordinate *coor;
3.在mainfrm.cpp中,新增一個結構體變數
//new一個結構體參數
coor = new coordinate;
4.在按鈕的事件中給予座標值,呼叫函式moveTo(),把結構體指標 coor 及圖紙物件指標 myLab 傳進去,移動處理後,再把 myLab 指給Image1物件。
//move 按鈕的事件 右下朝左上
void __fastcall TForm1::Button2Click(TObject *Sender)
{
coor->ori_w=640;
coor->ori_h=480;
coor->off_x=240; //矩形對原點偏移x(左上點)
coor->off_y=180; //矩形對原點偏移y
coor->box_w=160;
coor->box_h=120;
coor->mov_x=160; //tar x = off_x-80
coor->mov_y=100; //tar y = off_y-80
moveTo(myLab,coor);
Image1->Picture->Bitmap=myLab;
}
//back 按鈕的事件 左上朝右下
void __fastcall TForm1::Button3Click(TObject *Sender)
{
coor->ori_w=640;
coor->ori_h=480;
coor->off_x=160; //矩形對原點偏移x(左上點)
coor->off_y=100; //矩形對原點偏移y
coor->box_w=160;
coor->box_h=120;
coor->mov_x=240; //tar x = off_x+80
coor->mov_y=180; //tar y = off_y+80
moveTo(myLab,coor);
Image1->Picture->Bitmap=myLab;
}
在 mylib.h中,移動處理函式moveTo()代碼。
//move to
void moveTo(Graphics::TBitmap *scr,coordinate *co){
Graphics::TBitmap *tmp;//開一塊 mem
tmp = new Graphics::TBitmap();
tmp->PixelFormat = pf24bit; //bmp
tmp->Height = co->ori_h;//圖紙 h
tmp->Width = co->ori_w;//圖紙 w
int i,j;
int len=co->ori_w*3;//line = (byte*) {B,G,R},{B,G,R}...
//設定底色
for(j=0;j<co->ori_h;j++){//initial value
memset(tmp->ScanLine[j],clBlack,len);//clBlack=0=0x00,clWhite=255=0xff
}
//開始複製 moveto tmp
for(i=0;i<co->box_w;i++){
for(j=0;j<co->box_h;j++){
tmp->Canvas->Pixels[i+co->mov_x][j+co->mov_y] =
scr->Canvas->Pixels[i+co->off_x][j+co->off_y];
}
}
//覆蓋回去 scr
for(j=0;j<co->ori_h;j++){
memcpy(scr->ScanLine[j],tmp->ScanLine[j],len);
}
delete tmp;
}
這樣就完成了
範例程式 IMGLab.rar