Zgryźliwość kojarzy mi się z radością, która źle skończyła.

 

Rozdział 12.
Programowanie grafiki i multimediów









\\printsrv\skład\Robin\Delphi 4 dla kazdego\12.doc              473









Rozdzia³ 12. ¨ Programowanie grafiki i multimediów              511

Programowanie grafiki i multimediów reprezentuje przyjemniejszą część pracy programistycznej. W tym rozdziale omawiany jest wstęp do programowania grafiki i multimediów z wykorzystaniem Delphi. W przypadku programowania grafiki większość tego wprowadzenia opiera się na analizie klas TCanvas i TBitmap.

Zaczniemy od spojrzenia na najprostsze techniki wyświetlania grafiki w Delphi. Później poznasz interfejs urządzeń graficznych Windows (GDI) i składające się na niego komponenty. W międzyczasie zapoznasz się z różnymi procedurami rysowania linii i kształtów, a także z różnymi sposobami wyświetlania bitmap. W dalszej części rozdziału omówione zostaną tzw. bitmapy pozaekranowe i korzyści płynące z ich zastosowania. Sekcje programowania multimediów dotyczą sposobów odtwarzania plików dźwiękowych przy wykorzystaniu interfejsu Windows API. Dowiesz się także, w jaki sposób odtwarza się pliki dźwiękowe MIDI i wideo AVI przy użyciu klasy TMediaPlayer.

Grafika w prosty sposób

Programowanie grafiki niekoniecznie musi być trudne. Czasami wszystko, co trzeba zrobić, sprowadza się do wyświetlenia obrazu lub kształtu w formularzu. Biblioteka VCL udostępnia gotowe komponenty przeznaczone do tych właśnie celów. Przed przystąpieniem do prawdziwego programowania grafiki przyjrzymy się niektórym z tych komponentów.

Komponent Shape (na zakładce Additional Palety Komponentów) umożliwia dodawanie do formularza figur geometrycznych o różnych kształtach. Jego użycie jest proste, wystarczy umieścić go w formularzu i ustawić według własnych potrzeb właściwości pędzla (Brush), pióra (Pen) i kształtu (Shape). Teraz można przystąpić do rysowania okręgów, elips, kwadratów i prostokątów (również z zaokrąglonymi narożnikami). Właściwość Brush wpływa na kolor tła, właściwość Pen zmienia kolor i grubość krawędzi figur.

Do wyświetlenia bitmapy w formularzu służy komponent Image. Znajduje on wiele zastosowań przy operacjach graficznych, włączając w to tworzenie tła formularza w postaci bitmapy. Właściwość Picture klasy TImage jest obiektem klasy TPicture. Wyboru obrazu można dokonać na etapie projektowania poprzez Inspektor Obiektów lub poprzez ładowanie w trakcie pracy programu. Poniższy przykład pokazuje, jak można zmienić rysunek w trakcie pracy programu:

 

Image1.Picutre.Bitmap.LoadFromFile('tlo.bmp');

Właściwość Stretch określa, czy rysunek będzie rozciągany lub kompresowany w celu dopasowania go rozmiaru komponentu. Właściwość Center decyduje o tym, czy bitmapa będzie wycentrowana względem komponentu. Właściwość AutoSize może posłużyć do zmuszenia komponentu do dopasowania własnych rozmiarów do rozmiaru rysunku.

Wspomnę również o komponencie PaintBox. Udostępnia on prostokątny obszar w postaci tzw. płótna (ang. canvas), stanowiącego arenę wszelkich operacji graficznych. Płótno to reprezentowane jest przez jego właściwość Canvas, będącą obiektem klasy TCanvas; klasa ta odpowiedzialna jest za większość operacji graficznych wykonywanych przez Delphi – poświęcam jej następną sekcję niniejszego rozdziału.

Kontekst urządzenia i klasa TCanvas

Windows stosuje termin kontekst urządzenia do opisania obszaru (płótna), na którym można tworzyć grafikę. Kontekst urządzenia może być wykorzystany do rysowania na wielu powierzchniach, w szczególności:

u                                          w obszarze okna użytkownika lub jego ramce

u                                          na Pulpicie

u                                          w pamięci

u                                          na drukarce lub innym urządzeniu wyjściowym

To tylko niektóre przykłady. Istnieją również inne, mniej oczywiste konteksty urządzeń (np. menu), ale te przedstawione powyżej będą najważniejsze z Twojego punktu widzenia.

Korzystanie z kontekstów urządzeń na poziomie API może być dosyć kłopotliwe. Po pierwsze, trzeba uzyskać uchwyt do kontekstu urządzenia od systemu Windows. Następnie trzeba utworzyć szereg różnych obiektów wymaganych przez kontekst (pióra, pędzle, czcionki itp.). Dopiero po tych czynnościach można przystąpić do rysowania. Po skończeniu rysowania trzeba dopilnować, aby obiekty, wybrane uprzednio dla kontekstu, zostały zwolnione przed samym zwolnieniem kontekstu urządzenia. Jeżeli nie zostanie to zrobione, aplikacja korzystająca z tego kontekstu spowoduje zagubienie pamięci – zajętej przez nie zwolnione obiekty i niedostępnej w żaden sposób aż do końca sesji Windows.

Jak więc widać, zabawa z kontekstami urządzeń jest na ogół mało przyjemna.

Dobrą wiadomością jest jednak to, że biblioteka VCL upraszcza cały ten proces, udostępniając klasę TCanvas. Oto krótki przykład – poniższy fragment kodu korzysta z interfejsu API, aby narysować na ekranie koło o niebieskiej krawędzi i czerwonym wnętrzu:

 

procedure TForm1.Button1Click(Sender: TObject);

var

  DC : HDC;

  Brush, OldBrush: HBrush;

  Pen, OldPen : HPen;

begin

  DC:=GetDC(Handle);

  Brush:=CreateSolidBrush(RGB(255,0,0));

  Pen:=CreatePen(PS_SOLID, 1, RGB(0,0,255));

  OldBrush:=SelectObject(DC, Brush);

  OldPen:=SelectObject(DC, Pen);

  Ellipse(DC, 20,20,120,120);

  SelectObject(DC, OldBrush);

  SelectObject(DC, OldPen);

  ReleaseDC(Handle, DC);

end;

Kod ten nie wygląda znowu tak strasznie, ale mimo wszystko łatwo można zapomnieć o przywróceniu poprzednich ustawień obiektów po zakończeniu rysowania. Kiedy coś takiego się zdarzy, w aplikacji wystąpi gubienie zasobów.

Teraz zobacz, jak wygląda równoważny kod napisany za pomocą biblioteki VCL:

 

Canvas.Brush.Color:= clRed;

Canvas.Pen.Color:= clBlue;

Canvas.Ellipse(20,20,120,120);

Kod ten jest nie tylko krótszy i czytelniejszy, ale również o wiele pewniejszy. Klasa TCanvas sama dba o to, aby w miarę potrzeby zwolnić zasoby, zwalniając programistę z tego obowiązku. Jest więc narzędziem o wiele poręczniejszym niż funkcje API.

Najważniejsze właściwości i metody klasy TCanvas przedstawione są w tabelach 12.1 i 12.2; większość z nich opiszę dokładniej w dalszej części rozdziału.

Tabela 12.1. Główne właściwości klasy TCanvas

Właściwość

Opis

Brush

Zawiera kolor pędzla lub wzór stosowany do wypełniania figur.

ClipRect

Określa prostokątny wycinek płótna, do którego dodatkowo ograniczone jest tworzenie grafiki. Właściwość tylko do odczytu.

CopyMode

Określa sposób tworzenia grafiki w kontekście bieżącej zawartości obszaru (normalnie, inwersyjne, xor itd.)

Font

Określa rodzaj czcionki stosowanej przez płótno do wypisywania tekstu.

Handle

Zawiera uchwyt, stanowiący kontekst urządzenia (HDC) płótna, stosowany podczas bezpośrednich wywołań funkcji API.

Pen

Określa styl i kolor linii rysowanych na płótnie.

PenPos

Zawiera bieżącą pozycję rysowania wyrażoną przez współrzędne x i y.

Pixels

Reprezentuje poszczególne piksele płótna w postaci macierzy

Tabela 12.2. Główne metody klasy TCanvas

Metoda

Opis

Arc

Rysuje łuk korzystając z bieżących ustawień pióra.

BrushCopy

Wyświetla bitmapę z przezroczystym tłem.

CopyRect

Kopiuje fragment obrazu na płótno.

Draw

Kopiuje obraz z pamięci na płótno.

Ellipse

Rysuje elipsę, korzystając z bieżących ustawień pióra (dla krawędzi) i pędzla (dla wypełnienia wnętrza).

FloodFill

Wypełnia obszar na płótnie zgodnie z bieżącymi ustawieniami pędzla.

LineTo

Rysuje odcinek linii prostej od bieżącego punktu do pozycji wyznaczonej przez parametry x i y.

MoveTo

Ustawia nową pozycję bieżącego punktu rysowania.

Pie

Rysuje wycinek koła – zgodnie z bieżącymi ustawieniami pióra i pędzla.

Polygon

Rysuje wielokąt na podstawie danych z tablicy punktów i wypełnia go zgodnie z bieżącymi ustawieniami pędzla.

Polyline

Rysuje linię łamaną na podstawie punktów z tablicy i bieżących ustawień pióra. Linia nie jest automatycznie domykana.

Rectangle

Rysuje prostokąt, korzystając z bieżących ustawień pióra (dla krawędzi) i pędzla (dla wypełnienia wnętrza).

RoundRect

Rysuje wypełniony prostokąt z zaokrąglonymi narożnikami.

StretchDraw

Kopiuje bitmapę z pamięci na płótno. Bitmapa jest rozciągana lub skracana w zależności od rozmiaru obszaru przeznaczenia.

TextExtent

Zwraca szerokość i wysokość (w pikselach) łańcucha przekazanego przez parametr Text. Szerokość jest obliczana na podstawie bieżącej czcionki płótna.

TextHeight

Zwraca wysokość (w pikselach) łańcucha przekazanego przez parametr Text. Szerokość jest obliczana na podstawie bieżącej czcionki płótna.

TextOut

Wypisuje tekst na płótnie od określonego położenia, korzystając z bieżącej czcionki.

TextRect

Wypisuje tekst w ramach ograniczonego obszaru.

Powyższe właściwości i metody reprezentują jedynie małą część funkcjonalności kontekstu urządzenia Windows, niemniej jednak dzięki nim będziesz w stanie wykonać 80% zadań związanych z tworzeniem grafiki. Zanim jednak przejdziemy do szczegółowego omawiania klasy TCanvas, musisz wcześniej dowiedzieć się co nieco na temat obiektów graficznych stosowanych przy programowaniu w Windows.

Obiekty GDI

Interfejs urządzeń graficznych Windows (GDI) składa się z wielu typów obiektów, które definiują funkcjonowanie kontekstu urządzenia. Najczęściej stosowanymi obiektami GDI są pióra, pędzle i czcionki. Inne obiekty GDI to palety, bitmapy i regiony. Przyjrzyjmy się najpierw piórom, pędzlom i obiektom, by późnij przejść do obiektów bardziej skomplikowanych.

Pióra, pędzle i czcionki

Pióra, pędzle i czcionki są prostymi obiektami. Zajmiemy się każdym z nich z osobna, aby przekonać się, w jaki sposób korzysta z nich klasa TCanvas.

Pióra

Pióro definiuje obiekt, którego przeznaczeniem jest rysowanie linii. Może to być prosta linia rysowana od jednego punktu do drugiego lub krawędź rysowana wokół prostokątów, elips i wielokątów. Dostęp do pióra, będącego obiektem klasy TPen, następuje poprzez właściwość Pen klasy TCanvas. Właściwości klasy TPen zostały przedstawione w tabeli 12.3.

Tabela 12.3. Właściwości klasy TPen

Właściwość

Opis

Color

Ustala kolor linii.

Handle

Zawiera kontekst urządzenia pióra (HDC). Stosowany podczas bezpośrednich odwołań do GDI.

Mode

Określa sposób w jaki linia będzie rysowana w kontekście bieżącej zawartości obszaru (normalny, inwersyjny, xor, itd.).

Style

Określa styl pióra. Może to być styl ciągły, kropkowy, kreskowy,
kropkowo-kreskowy, czysty lub inny....

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • hannaeva.xlx.pl