Hlavní
Hlavní strana
Seznam článků
Nejčtenější články
Progres e-mailem
Visual C++ FAQ

Seriály
COM
ISAPI

banner2.gif (2546 bytes)

Nenechte si ujít
Neobdélníková okna
Tisk bez Preview
MFC a DLL
Logo v MDI ploše
Kouzla s kombo-boxem
Výjimky v C++

banner.gif (3305 bytes)

Průhledné bitmapy 1.díl Jan Odvárko
16.11.1999
[Hlavní stránka]  |  [Rubrika]  |  [Download]

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.

jo_131199_transparentbitmap1_obr1.gif (8406 bytes)

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(00, bmp.bmWidth, bmp.bmHeight, &oMemDC, 00, 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.

jo_131199_transparentbitmap1_obr2.gif (5019 bytes)

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.

jo_131199_transparentbitmap1_obr3.gif (2612 bytes)

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(00, bmp.bmWidth * 2, bmp.bmHeight, &oMemDC, 00,
    bmp.bmWidth, bmp.bmHeight, SRCCOPY);

Výsledek by pak je následující.

jo_131199_transparentbitmap1_obr4.gif (2704 bytes)

Příště rastrové operace...


Podobné články:

 
Článek je zařazen do seriálu Následující>>
Průhledné bitmapy 2.díl

Kdo Otázka nebo připomínka

Prohlížení příspěvků nebo nový příspěvek

O firmě...

Kontakt

Ostatní