1.1 ┌vod
Vykreslovßnφ bitmap jednou z nejΦast∞jÜφch operacφ v oblasti grafickΘho v²stupu.
Jednφm ze znßm²ch problΘm∙ p°i kreslenφ t∞chto obrßzk∙ je pak zajiÜt∞nφ
"pr∙hlednosti", tzn. ΦßsteΦnΘ zachovßnφ p∙vodnφho pozadφ. V
nßsledujφcφm Φty°dφlnΘm serißlu si ukß₧eme jak tento problΘm °eÜit pomocφ
rastrov²ch operacφ a souvisejφcφ metody BitBlt (StretchBlt). Krok za
krokem si rozebereme cel² postup kreslenφ bitmap na typickΘm p°φkladu a ukß₧eme si
jakΘ mo₧nosti nßm zmφn∞nß metoda dßvß
1.2 Vykreslenφ bitmapy
NejjednoduÜÜφ zp∙sob pou₧itφ obrßzku v aplikaci je pou₧itφ standardnφ bitmapy,
kterß je ulo₧ena ve zdrojφch aplikace.Takovou bitmapu lze pak velice jednoduÜe nahrßt
pou₧itφm metody LoadBitmap a vykreslit na obrazovku metodou BitBlt (v
p∙vodnφ velikosti). DalÜφ mo₧nostφ je pou₧itφ metody StretchBlt, kterß
umo₧≥uje zm∞nu v²slednΘ velikosti bitmapy. NaÜφm prvnφm p°φkladem tedy bude
ukßzka vykreslenφ bitmapy.
Prvnφm krokem je vlo₧enφ bitmapy do zdroj∙ aplikace. Tato akce je
jednoduchß a lze ji provΘst nap°φklad volbou Insert->Resource z hlavnφho
menu. Ve vyvolanΘm dialogu zvolφme typ zdroje Bitmap a ukonΦφme tlaΦφtkem New.
Pomocφ jednoduch²ch prost°edk∙ Visual C++ lze nynφ bitmapu editovat.
V zßhlavφ p°edchozφho obrßzku je patrnΘ symbolickΘ jmΘno
(definovanΘ pomocφ p°φkazu preprocesoru - #define) IDB_FROG,
kterΘ pou₧φvßme pro identifikaci bitmapy. Toto jmΘno je reprezentovßno Φφselnou
konstantou jejφ₧ hodnotu m∙₧eme v p°φpad∞ pot°eby nalΘzt v hlaviΦkovΘm souboru resource.h.
Z obrßzku je dßle patrnΘ pozadφ, kterΘ je vypln∞no Φervenou barvou. Tato barva
bude pozd∞ji prohlßÜena za "pr∙hlednou".
DalÜφm krokem je nahrßnφ vytvo°enΘ bitmapy ze zdroj∙. Pro
tento ·kol vyu₧ijeme t°φdy CBitmap z knihovny MFC a jejφ metodu LoadBitmap.
Pokud se bitmapu ze zdroj∙ aplikace nepoda°φ nahrßt, vrßtφ tato metoda hodnotu FALSE.
Nßsledujcφ zdrojov² k≤d ukazuje pou₧itφ tΘto t°φdy a metody.
CBitmap oBitmap;
if (!oBitmap.LoadBitmap(IDB_FROG))
return; |
Nynφ nezb²vß, ne₧ bitmapu vykreslit. Je mo₧nß trochu
p°ekvapujφcφ, ₧e t°φda CBitmap nemß metodu Draw, ale pozd∞ji
nßm bude jasnΘ proΦ. TakΘ algoritmus kreslenφ bitmapy nenφ tak trivißlnφ, jak
bychom Φekali. Podφvejme se op∞t nejd°φve na ukßzku zdrojovΘho k≤du.
CDC oMemDC;
if (!oMemDC.CreateCompatibleDC(pDC))
return;
BITMAP bmp;
oBitmap.GetBitmap(&bmp);
CBitmap* pOldBitmap = oMemDC.SelectObject(&oBitmap);
pDC->BitBlt(0, 0, bmp.bmWidth, bmp.bmHeight, &oMemDC, 0, 0, SRCCOPY);
oMemDC.SelectObject(pOldBitmap); |
Jak je z ukßzky vid∞t, bitmapu nelze vytisknout p°φmo. Je nutnΘ
vytvo°it doΦasn² pam∞¥ov² kontext za°φzenφ (oMemDC), do kterΘho bitmapu
vlo₧φme a odkud ji metodou BitBlt p°emφstφme do skuteΦnΘho (cφlovΘho)
kontextu za°φzenφ pDC.
Tento princip jednoduÜe vyu₧φvß toho, ₧e bitmapa m∙₧e ve Windows
p°edstavovat pseudo vstupn∞/v²stupnφ za°φzenφ. Jak takΘ vidφme z p°edchozφho
obrßzku, kontext vlastn∞ p°edstavuje vstupnφ bod k tomuto za°φzenφ a metody BitBlt
a StrecthBlt umo₧≥ujφ provßd∞t rastrovΘ operace (p°esuny bitov²ch map)
mezi t∞mito kontexty. Pozorn² Φtenß° si jist∞ povÜimne, ₧e operace lze provßd∞t
ob∞ma sm∞ry, m∙₧eme nap°φklad snφmat obsah obrazovky (videopam∞ti).
Nynφ se m∙₧eme vrßtit k naÜemu p°φkladu. Prvnφm krokem je
vytvo°enφ pam∞¥ovΘho kontextu za°φzenφ oMemDC, kter² je kompatibilnφ s
obrazov²m kontextem pDC. K tomuto ·Φelu pou₧ijeme metodu CreateCompatibleDC.
Pro zjiÜt∞nφ velikosti vykreslovanΘ bitmapy pou₧ijeme metody GetObject,
kterß inicializuje p°edanou strukturu BITMAP. V dalÜφm kroku vybereme
bitmapu, volßnφm metody SelectObject do pam∞¥ovΘho kontextu a vytiskneme ji
pomocφ BitBlt. (tato metoda pou₧φvß rastrovou operaci SRCCOPY).
Nßvratovou hodnotou metody SelectObject je p∙vodnφ objekt (p∙vodnφ bitmapa)
v kontextu, kter² musφme po ukonΦenφ tisku vrßtit. HlaviΦka metody BitBlt
je nßsledujφcφ.
BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC,
int xSrc, int ySrc, DWORD dwRop ); |
|
|
x
|
Logickß x-ovß sou°adnice levΘho hornφho rohu cφlovΘho obdΘlnφku. |
y |
Logickß y-ovß sou°adnice levΘho hornφho rohu cφlovΘho obdΘlnφku. |
nWidth |
èφ°ka cφlovΘho obdΘlnφku (v bodech). |
nHeight |
V²Üka cφlovΘho obdΘlnφku (v bodech). |
pSrcDC |
Ukazatel na zdrojov² kontext za°φzenφ. Pokud je pou₧ita rastrovß
operace, kterß nezahrnuje zdroj musφ b²t nastaveno na NULL. |
xSrc |
Logickß x-ovß sou°adnice levΘho hornφho rohu ve zdrojovΘ bitmap∞,
odkud zaΦne kopφrovßnφ. |
ySrc |
Logickß y-ovß sou°adnice levΘho hornφho rohu ve zdrojovΘ bitmap∞,
odkud zaΦne kopφrovßnφ. |
dwRop |
Typ provedenΘ rastrovΘ operace. Tato operace definuje kombinaci barev ve
v²slednΘ operaci. Tato operace m∙₧e zahrnovat aktußlnφ Üt∞tec, zdrojovou bitmapu
nebo cφlovou bitmapu. |
Pokud bychom p°i vykreslovßnφ bitmapy cht∞li m∞nit jejφ velikost,
pou₧ijeme metodu StretchBlt. Tato metoda se od p°edchßzejφcφ liÜφ pouze
dv∞ma parametry.
BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC,
int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop ); |
|
|
nSrcWidth |
èφ°ka zdrojovΘho obdΘlnφku (v bodech). |
nSrcWidth |
V²Üka zdrojovΘho obdΘlnφku (v bodech). |
V²sledek naÜeho p°φkladu je znßzorn∞n na nßsledujφcφm
obrßzku.
Pokud bychom cht∞li p°i tisku bitmapy m∞nit jejφ velikost m∙₧eme
pou₧φt metodu BitBlt. Podφvejme se na ukßzku volßnφ tΘto metody.
pDC->StretchBlt(0, 0, bmp.bmWidth * 2, bmp.bmHeight, &oMemDC, 0, 0,
bmp.bmWidth, bmp.bmHeight, SRCCOPY); |
V²sledek by pak je nßsledujφcφ.
P°φÜt∞ rastrovΘ operace... |