Referát sa zaoberá objektom typu TBitmap, ktorý predstavuje rastrový obrázok a jeho využitím v programovaní. Popisuje, ako deklarovať smerník na bitmapu, vytvárať a manipulovať s bitmapami, a vysvetľuje koncepty konštruktorov a deštruktorov v objektovo orientovanom programovaní.
- TBitmap predstavuje rastrový obrázok zložený z matice pixlov.
- Smerník na objekt TBitmap sa deklaruje pre dynamické vytváranie objektov.
- Konštruktor automaticky inicializuje objekt, zatiaľ čo deštruktor uvoľňuje pamäť.
- Bitmapy môžeme ukladať a načítať zo súborov pomocou metód SaveToFile a LoadFromFile.
- Animované obrázky a pohyblivé objekty môžeme implementovať pomocou tried a metód.
Bitmapa
Objekt typu TBitmap - skrátene bitmapa:
- predstavuje rastrový obrázok - t.j. obrázok zložený z matice pixlov,
- je uložená v pamäti počítača,
- umožňuje pracovať so súbormi typu *.bmp,
- má vlastnú grafickú plochu (Canvas), do ktorej môžeme kresliť známymi príkazmi,
- bitmpu môžeme nakresliť do inej grafickej plochy (aj do inej bitmapy).
Deklarujeme smerník na objekt typu TBitmap:
Graphics::TBitmap *b;
1. Čo znamená Graphics::
Operátor :: sa používa pri určení oboru viditeľnosti metódy, triedy, premennej a podobne. Trieda TBitmap je definovaná v knižnici Graphics. Úplne iný typ, ale s rovnakým názvom je definovaný aj v knižnici Windows. Pritom sa tieto knižnice štandarde používajú v našich programoch. Ak napíšeme iba: TBitmap b; ... vznikne chyba: Ambiguity between 'TBitmap' and 'Windows::TBitmap' To znamená, že kompilátor sa nevie rozhodnúť, ktorý typ TBitmap chceme používať. Operátorom :: určíme typ presne.
2. Prečo je deklarovaný smerník na objekt a nie objekt:
Kvôli kompatibilite objektov s inými programovacími jazykmi. Objekty typu TBitmap nesmú byť statické, ale musia sa vytvárať ako premenné">dynamické premenné. Preto deklarujeme smerník na objekt typu TBitmap, samotný objekt vytvoríme ako dynamickú premennú. Smerník použijeme na to, aby sme s objektom mohli pracovať.
Graphics::TBitmap *b;
void __fastcall TForm1::FormCreate(TObject *Sender) // udalosť OnCreate { b=new Graphics::TBitmap; // vytvoríme bitmapu b->Width=256; // nastavíme rozmery bitmapy: šírka b->Height=256; // výška (inak by mala bitmapa nulové rozmery) int x, y; for (y=0; yPixels[x][y]=TColor(RGB (x, y, 0)); // bitmapa má svoju grafickú plochu, do ktorej sa dá kresliť }
void __fastcall TForm1::FormDestroy(TObject *Sender) // udalosť OnDestroy { delete b; // pri skončení zrušíme bitmapu }
void __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { if (!Shift.Contains(ssLeft)) return; Image1->Canvas->Draw(X-128, Y-128 ,b); // do Image1 sa nakreslí bitmapa }
Bitmapu môžeme triviálnym spôsobom uložiť do súboru alebo prečítať zo súboru:
- b->SaveToFile("farby.bmp" ); // ulož do súboru
- b->LoadFromFile("farby.bmp&quo t;); // prečítaj zo súboru
Animované obrázky
Graphics::TBitmap *b[8]; int Faza=0; int X=300;
void __fastcall TForm1::FormCreate(TObject *Sender) { int i; for (i=0; iLoadFromFile("zajo" +IntToStr(i)+".bmp"); b[i]->Transparent=true; } }
void __fastcall TForm1::FormDestroy(TObject *Sender) { int i; for (i=0; iCanvas->FillRect(Image1-&g t;ClientRect); Image1->Canvas->Draw(X, 100, b[Faza]); Faza=(Faza+1)%8; X=X-15; }
Kompletný program aj s obrázkami
Konštruktor a deštruktor objektu
Bitmapy budeme často používať ako súčasť nejakého objektu:
class TCosi {
private:
Graphics::TBitmap *b;
public:
void Inic(); void Uprac(); ... };
void TCosi::Inic() { b=new Graphics::TBitmap; b->LoadFromFile("obrazok.bmp&q uot;); }
void TCosi::Uprac() { delete b; }
TCosi c; c.Inic(); ... c.Uprac();
Vidíme, že pri inicialozovaní objektu sa bitmapa vytvorí a prečíta, pri skončení práce s objektom sa bitmapa uvoľní.
Takéto informatika/programovanie-pokus-o-vypracovanie-poziadaviek-na-skusku-z-predmetu/" class="wiki-link" title="Viac o: programovanie">programovanie je náchylné na chyby:
- nesmieme zabúdať objekt inicializovať (inak by neexistovala bitmapa),
- pri skončení práce s objektom musíme volať metódu Uprac() (inak by sme zaplnili pamäť obrázkami, ktoré už nikdy nebudeme potrebovať).
Pomocou dvoch špeciálnych metód - konštruktora a deštruktora, je inicializovanie a upratovanie objektu elegantnejšie:
- konštruktor objektu je metóda, ktorá sa automaticky vykoná ihneď po tom, ako objekt v pamäti vznikol - napríklad, v konštruktore vytvoríme bitmapu a prečítame ju zo súboru,
- deštruktor objektu je metóda, ktorá sa automaticky vykoná pred tým, ako sa objekt zruší - napríklad, v deštruktore zrušíme bitmapu.
TCosi s využitím konštruktora a deštruktora:
class TCosi {
private:
Graphics::TBitmap *b;
public:
TCosi(); // konštruktor ~TCosi(); // deštruktor ... };
TCosi::TCosi() { b=new Graphics::TBitmap; b->LoadFromFile("obrazok.bmp&q uot;); }
TCosi::~TCosi() { delete b; }
Pri deklarácii:
TCosi c; ... sa automaticky zavolá konštruktor objektu c
Ak je c globálna premenná, deštruktor sa zavolá automaticky pri skončení programu. Ak je c lokálna premenná, deštruktor sa zavolá automaticky pri skončení volania funkcie.
Všimnime si, že:
- konštruktor objektu je metóda, ktorá má špeciálne meno - je zhodné s menom objektovej triedy: TCosi(),
- meno deštruktora objektu začína ~ (vlnovkou), za ktorým nasleduje meno objektovej triedy: ~TCosi(),
- konštruktor nemôžeme a deštruktor nesmieme zavolať priamo z programu - teda nesmieme: c.~TCosi();
- konštruktor môže mať aj parametre, deštruktor ich nesmie mať,
- konštruktor ani deštruktor nevracajú žiadne hodnoty.
Konštruktor s parametrami
Objektová trieda môže mať viacej konštruktorov, musia sa však líšiť v parametroch (deštruktor je vždy iba jeden a bez parametrov). Pridáme ešte jeden konštruktor s parametrom: class TCosi {
private:
Graphics::TBitmap *b;
public:
TCosi(); // základný konštruktor TCosi(AnsiString Meno); // konštruktor s parametrom ~TCosi(); // deštruktor ... };
TCosi::TCosi() { b=new Graphics::TBitmap; b->LoadFromFile("obrazok.bmp&q uot;); }
TCosi::TCosi(AnsiString Meno) { b=new Graphics::TBitmap; b->LoadFromFile(Meno); }
TCosi::~TCosi() { delete b; }
Potom:
TCosi c; ... volá sa základný konštruktor TCosi d("Mesiac.bmp"); ... volá sa konštruktor s parametrom TCosi *p; p=new TCosi("Mesiac.bmp"); ... volá sa konštruktor s parametrom
Každá trieda by mala mať základný konštruktor (tzv. default constructor). Aj keď sme do dnešného dňa konštruktory nepoznali, kompilátor za nás vždy definoval základný konštruktor.
Pozor: Ak by sme v triede TCosi definovali iba konštruktor s parametrom (ale nedefinovali by sme základný konštruktor), mohli by sme mať problémy s deklaráciou:
TCosi c; ... chyba, kompilátor nepozná základný konštruktor TCosi c("obrazok.bmp"); ... ok, kompilátor zavolá konštruktor s parametrom
Pohyblivé objekty
Pohyb jednoduchých útvarov po obrazovke sme programovali podľa nasledujúcej schémy:
- vykonali sme zmenu (počítadla, polohy, stavu útvaru),
- zmazali obrázok,
- do čistého obrázka sme nakreslili útvary, ktoré tvoria scénu.
Aj teraz budeme postupovať rovnako, ale s tým, že využijeme objekty. Skúsime vytvoriť jednoduchý program - loptu, ktorá sa odráža od okrajov hracej plochy:
- plocha má rozmery 400x300 obrazových bodov
- potrebné obrázky sú uložené v súboroch: pozadie.bmp, lopta.bmp.
class TLopta {
private:
Graphics::TBitmap *b; int X, Y, dX, dY;
public:
TLopta(); // inicializuje objekt (vytvorí a nahrá bitmapu, ...) ~TLopta(); // uvoľní bitmapu void Pohni(); // vykoná pohyb objektu (1 krok animácie) void Kresli(); // nakreslí objekt (bitmapu) };
TLopta::TLopta() { b=new Graphics::TBitmap; b->LoadFromFile("Lopta.bmp&quo t;); b->TransparentColor=clRed; // červená bude priesvitná farba b->Transparent=true; // povolíme priesvitnosť X=200; Y=100; dX=1+random(10); dY=1+random(10); }
TLopta::~TLopta() { delete b; }
void TLopta::Pohni() { X=X+dX; Y=Y+dY; if (XWidth/2) { X=b->Width/2; dX=-dX; } if (YHeight/2) { Y=b->Height/2; dY=-dY; } if (X>300-b->Width/2) { X=300-b->Width/2; dX=-dX; } if (Y>300-b->Height/2) { Y=300-b->Height/2; dY=-dY; } }
void TLopta::Kresli() { Form1->Image->Canvas->Draw(X-b- >Width/2, Y-b->Height/2, b); }
//-------------------------------------- -----------------------------------
TLopta l; Graphics::TBitmap *poz; // smerník na bitmapu s pozadím
void __fastcall TForm1::FormCreate(TObject *Sender) { poz=new Graphics::TBitmap; // vytvoríme a nahráme bitmapu pozadia: poz->LoadFromFile("pozadie.bmp "); }
void __fastcall TForm1::FormDestroy(TObject *Sender) { delete poz; // uvoľníme pozadie }
void __fastcall TForm1::Timer1Timer(TObject *Sender) { l.Pohni(); // vykonáme pohyb Image->Canvas->Draw(0, 0, poz); // nakreslíme pozadie l.Kresli(); // nakreslíme loptu }
Program môžeme triviálne upraviť tak, aby sa na obrazovke hýbalo veľa lôpt: TLopta l[10];
void __fastcall TForm1::Timer1Timer(TObject *Sender) { int i; for(i=0; iCanvas->Draw(0, 0, poz); for(i=0; iWidth=šírka; b->Height=výška; o prečítať obrázok zo súboru: b->LoadFromFile(meno_súboru); o nakresliť bitmapu do grafickej plochy: Image1->Canvas->Draw(x, y, b); o kresliť do maliarskeho plátna bitmapy: b->Canvas-> ... *
po skončení práce treba bitmapu uvoľniť: delete b;
Konštruktor je špeciálna metóda, ktorá:
- sa automaticky zavolá ihneď potom, ako objekt v pamäti vznikne,
- slúži na inicializovanie objektu (nastavenie hodnôt, vytvorenie dynamických premenných, ktoré sa v objekte používajú a pod.),
- má špeciálne meno, ktoré sa zhoduje s menom triedy, do ktorej konštrukor patrí,
- môže mať parametre (je však výhodné, ak v triede existuje aj konštruktor bez parametrov - tzv. základný konštruktor),
- nevracia hodnotu.
Deštruktor je špeciálna metóda, ktorá:
- sa automaticky zavolá tesne pred tým, ako objekt zaniká,
- slúži na upratanie objektu (zrušenie dynamických premenných, ktoré objekt vytvoril a pod.),
- má špeciálne meno, ktoré začína ~ a zvyšok mena sa zhoduje s menom triedy, do ktorej deštruktor patrí,
- nemá parametre,
- nevracia hodnotu.
🤔 Najčastejšie otázky k téme
Čo je to TBitmap?
TBitmap je objekt, ktorý reprezentuje rastrový obrázok a umožňuje manipuláciu s grafickými plochami v programovaní.
Prečo sa používa smerník na objekt TBitmap?
Smerník sa používa na dynamické vytváranie objektov, čo je potrebné pre kompatibilitu s inými programovacími jazykmi.
Aký je účel konštruktora a deštruktora v triede?
Konštruktor slúži na automatické inicializovanie objektu, zatiaľ čo deštruktor sa stará o uvoľnenie pamäte pred zánikom objektu.