Visual 6


Visual 6

Grafika

GDI+

GDI+ (Graphics Device Interface) jest reprezentowany przez przestrzeń nazw System.Drawing w .NET Framework. Dostarcza klas pozwalających na wykorzystanie możliwości graficznych systemu. GDI+ wprowadza między innymi następujące mechanizmy:

Przestrzenie nazw GDI+

Wszystkie klasy (typy) w bibliotece .NET zgrupowane są w przestrzeniach nazw.

Przestrzeń nazw jest zbiorem klas dostarczających podobnej funkcjonalności, np.

klasy związane z formami, zgrupowane sa w przestrzeni nazw Windows.Forms, klasy

związane z obsługą dostępu do baz danych w przestrzeni nazw Data.

Interfejs GDI+ jest zdefiniowany w następujących przestrzeniach nazw:

System.Drawing

Przestrzeń nazw System.Drawing dostarcza podstawowej funkcjonalności interfejsu

GDI+. Zawarta jest w niej definicja podstawowych klas Brush,Pen,Graphics,Font itd. Klasa Graphics odgrywa ważną rolę w interfejsie GDI+ i zawiera metody służące do rysowania na urządzeniu graficznym. Poniższa tabela zawiera wykaz wybranych

klas przestrzeni nazw System.Drawing:

Tabela 1. Wybrane klasy przestrzeni nazw System.Drawing

0x08 graphic

Tabela 2. Wybrane struktury przestrzeni nazw System.Drawing

Struktura

Opis

Color

reprezentuje kolor ARGB

Point,

PointF

reprezentuje punkt na płaszczyźnie, współrzędne x,y w przypadku Points , a typu Integer, w przypadku PointF typu Double

Rectangle, RectangleF

Reprezentuje prostokąt opisany

przez współrzędne lewego górnego rogu oraz prawego dolnego rogu

Size

reprezentuje rozmiar szerokość oraz wysokość

System.Drawing.Design

Jest to przestrzeń w której umieszczone są klasy wspomagaj ące tworzenie nowych

Kontrolek aktualnie zawarte są w niej dwa typy klas: Edytory oraz narzędzia.

W skład edytorów wchodzą: BitmapEditor, FontEditor, ImageEditor, a

w skład narzędzi: ToolBoxItem, ToolBoxItemCollection.

System.Drawing.Drawing2D

Zawiera klasy oraz enumeratory przydatne do bardziej zaawansowanej grafiki wektorowej

na płaszczyźnie. Zawiera między innymi klasy reprezentujące gradientowy pędzel, macierz, ścieżki graficzne. Kilka podstawowych klas wchodzących w skład tej przestrzeni nazw przedstawia poniższa tabela:

Tabela 3. Wybrane klasy przestrzeni nazw System.Drawing.Drawing2D

Klasa

Opis

GraphicsPath

reprezentuje zbiór połączonych linii

oraz krzywych

LinearGradientBrush

pędzel z liniowym gradientem

Matrix

macierz reprezentująca transformacje geometryczne

:

Tabela 4. Wybrane enumeratory przestrzeni nazw System.Drawing.Drawing2D

Enumerator

Opis

QualityMode

jakość rysowanych obiektów interfejsu GDI+

SmoothingMode

sposób wygładzania krawędzi interfejsu GDI+

System.Drawing.Imaging

Dostarcza zaawansowanych funkcji GDI+ do manipulowania obrazami. Kodeki różnych

formatów graficznych.

System.Drawing.Printing

Definiuje klasy pozwalające aplikacji na komunikację z drukarką. Poniższa tabelka zawiera zestaw podstawowych klas wchodzących w skład tej przestrzeni nazw.

.

Tabela 5. Wybrane klasy przestrzeni nazw System.Drawing.Printing

Klasa

Opis

PageSettings

ustawienia strony

PaperSize

rozmiar papieru

PreviewPageInfo

informacje o podglądzie wydruku

dla pojedynczej strony

PrintController

kontroluje wydruk dokumentu

PrintDocument

wysyła wynik na drukarkę

PrinterResolution

ustawia rozdzielczość drukarki

PrinterSettings

ustawienia drukarki

System.Drawing.Text

Większość klas związanych z zarządzeniem czcionkami znajduje się w przestrzeni

nazw System.Drawing. Przestrzeń System.Drawing.Text dostarcza zaawansowane

mechanizmy typograficzne. Obecnie zdefiniowane są w niej trzy klasy FontCollection,

InstalledFontCollection oraz PrivateFontCollection.

Klasa Graphics

Klasa Graphics jest jądrem interfejsu GDI+. Nieważne jaką operację graficzną chcemy

Wykonać, musimy w końcu skorzystać z klasy Graphics. Jest kilka sposobów otrzymania obiektu klasy Graphic do wykorzystania w aplikacji. Jedną z nich jest otrzymanie go jako parametru metody OnPaint() formy, która jest metodą obsługującą komunikat Paint. Metoda ta posiada argument typu System.Windows.Forms.PaintEventArgs zawierający obiekt typu Graphics.

Private Sub Form1_Paint(ByVal sender As System.Object, _

ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles MyBase.Paint

Dim g As Graphics = e.Graphics

End Sub

Kiedy już mamy obiekt Graphics, to możemy wywoływać dowolne jego metody służące

Np. do malowania linii, elips, prostokątów, wielokątów, obrazków. Poniższa tabelka

zawiera wykaz niektórych metod klasy Graphics.

Tabela 6. Wybrane metody klasy Graphics

Metoda

Opis

DrawArc

rysowanie łuku

DrawBezier, DrawBeziers, DrawCurve

rysowanie krzywych Beziera

DrawEllipse

rysowanie elipsy lub okręgu

DrawImage

rysowanie obrazu

DrawLine

rysowanie linii

DrawPath

rysowanie obiektów zawartych w GraphicsPath

DrawPolygon

rysowanie wielokąta

DrawRectangle

rysowanie prostokąta

DrawString

rysowanie łańcucha znaków

FillEllipse

wypełniona elipsa

FillPath

wypełnione obiekty zdefiniowane w GraphicsPath

FillPolygon

wypełniony wielokąt

FillRectangle

wypełniony prostokąt

Jeżeli np. chcemy narysować elipsę, możemy posługując się obiektem Graphics wywołać metodę DrawEllipse, która posiada kilka wersji.

Private Sub Form1_Paint(ByVal sender As System.Object, _

ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles MyBase.Paint

Dim g As Graphics = e.Graphics

' rysowanie elipsy

g.DrawEllipse(Pens.Black, 10, 10, 30, 30)

End Sub

Powyższy kod spowoduje namalowanie elipsy wpisanej w prostokąt o współrzędnych

lewego górnego rogu (10, 10) oraz szerokości 30 i wysokości 30, a więc namalowany

zostanie okrąg.

0x01 graphic

Obiekty graficzne

Do malowania w GDI+ są używane obiekty graficzne. Np., aby namalować prostokąt

wypełniony kolorem, potrzebny nam jest obiekt reprezentujący kolor, oraz sposób

wypełnienia. Zdefiniowane są cztery podstawowe obiekty, które są wykorzystywane podczas pracy z GDI+.

Tabela 7. Podstawowe obiekty graficzne GDI+

0x08 graphic

W GDI+, każdy z tych obiektów reprezentowany jest jako klasa.

Klasa Pen

Pióro reprezentowane jest przez obiekt klasy Pen i służy do rysowaniałinii o zadanej grubości oraz stylu. Aby posłużyć si ę piórem możemy skorzystać z jednego z predefiniowanych piór zdefiniowanych w klasie Pens lub utworzyć własny obiekt.

Klasa Pen zawiera cztery konstruktory umożliwiające utworzenie nowego obiektu, a

różniące się parametrami. Możemy skonstruować nowy obiekt przekazując konstruktorowi

informacje na temat:

Przykładowy kod:

Dim p1 As Pen = new Pen(Color.Red)

Dim p2 As Pen = new Pen(Color.Red,5)

Dim p3 As Pen = new Pen(Brushes.Red)

Dim p4 As Pen = new Pen(Brushes.Red,5)

Struktura Color

Struktura Color reprezentuje kolor w postaci ARGB:

Tabela 8. Struktura Color

Składowa

Opis

A

kanał alfa

B

składowa niebieska koloru

G

składowa zielona koloru

R

składowa czerwona koloru

Możemy skonstruować kolor składający sięz dowolnej kombinacji składowych RGB:

Dim c As Color = Color.FromArgb(255,0,255)

Klasa Font

Klasa reprezentuje fonty, które tworzymy w celu namalowania napisu. Klasa Font pozwala na stworzenie fontów różnego typu, stylu, rozmiaru. Klasa posiada szereg

konstruktorów pozwalaj ących na tworzenie obiektów.

Style dost ępne dla tworzonych fontów przedstawione są w tabeli poniżej:

Tabela 9. Style czcionki FontStyle

0x08 graphic

Przykład utworzenia nowego obiektu Font:

Dim f As Font = new Font(”Times New Roman”,24)

Zegar analogowy

Nasz program będzie wyświetlał zegar analogowy. Część odpowiedzialna za pobieranie daty i godziny będzie identyczna jak w przypadku zegara cyfrowego. Istotna różnicą bedzie sposób wyświetlania i malowania zegara.

0x01 graphic

Rys.1. Zegar analogowy.

Najpierw utworzymy nowy projekt w języku VB.NET. Umieszczamy na formie komponent Timer. Zegar składa się z następujących elementów:

Musimy dokonać odpowiednich ustawień kontrolki Timer. W edytorze właściwości przestawiamy właściwość Enable na True, a Interval na 1000.

Najpierw napiszemy kod odpowiedzialny za malowanie tarczy zegara w postaci metody

DrawClock, wywoływanej w obsłudze zdarzenia Paint. Zaznaczamy formę i w edytorze właściwości przełączamy się na widok zdarzeń (Events), odszukujemy zdarzenie Paint i klikamy dwukrotnie myszka po prawej stronie.

Rysowanie tarczy zegara

Rysowanie tarczy zegara sprowadza siędo narysowania dwóch elips: jednej wypełnionej

Kolorem i drugiej w postaci konturu jak obwódki. Do rysowania elips posłużymy się metodami FillEllipse oraz DrawEllipse. Składowa klasy Form o nazwie ClientRectangle zawiera prostokąt definiujący obszar roboczy okna.

Deklarujemy zmienną p typu Pen, przypisujemy na nią pióro koloru czarnego, a

następnie modyfikujemy właściwość Width pióra, oznaczającą grubość pióra. Elipsa

obwódki malowana jest tym nowym piórem. Jako ostatni element malujemy wypełnioną elipsę w cetralnym punkcie tarczy.

Private Sub DrawClock(ByVal g As Graphics)

Dim b As Brush

b = Brushes.GhostWhite

g.FillEllipse(b, 10, 10, _

Me.ClientRectangle.Width - 20, _

Me.ClientRectangle.Height - 20)

Dim p As Pen = New Pen(Color.Black)

p.Width = 4

g.DrawEllipse(p, 10, 10, _

Me.ClientRectangle.Width - 20, _

Me.ClientRectangle.Height - 20)

Dim midX As Integer = ClientRectangle.Width / 2

Dim midY As Integer = ClientRectangle.Height / 2

g.FillEllipse(Brushes.Black, midX - 5, midY - 5, 10, 10)

End Sub

Wygląd aplikacji

Po dodaniu wywołania naszej metody DrawClock w obsłudze zdarzenia Paint w

następujący sposób: DrawClock(e.Graphics), kiedy uruchomimy program na ekranie

powinniśmy dostać to, co przedstawia rysunek 2

0x01 graphic

Rys.2. Zegar analogowy: tarcza zegara

Godziny

Kolejnym krokiem będzie namalowanie na tarczy zegara liczb reprezentujących godziny.

Najpierw jednak przypomnienie z matematyki.

Tarcza naszego zegara jest elipsą. Elipsę możemy opisać następującym równaniem:

0x01 graphic
(1)

gdzie a oraz b to długości półosi elipsy.

0x01 graphic

Rys.3. Geometra elipsy

Równanie (1) można zapisać w postaci parametrycznej:

0x01 graphic
(2)

Układ współrzędnych związany z oknem aplikacji ma punkt (0, 0) w górnym lewym

narożniku okna, wartości x rosną w prawo, natomiast y do dołu. Metoda rysująca elipsę dostaje parametry opisujące prostokąt, wewnątrz którego rysowana jest elipsa.

0x01 graphic

Rys.4. Elipsa w układzie współrzędnych okna

Możemy teraz wyznaczyć współrzędne do umieszczenia godzin, ponieważ wszystkie

malowane obiekty z użyciem GDI+ są wpisywane w prostokąt, tak samo jest w przypadku metody rysującej napis. Musimy wyznaczyć współrzędne prostokąta wewnątrz, którego umieścimy napis. Należy również uwzględnić, fakt, że godziny powinny być odpowiednio wyrównywane, np na górze zegara znajduje się godzina dwunasta, napis składający się z dwóch cyfr. Natomiast na dole godzina szósta, czyli jedna cyfra, cyfra reprezentująca godzinę szóstą powinna być wycentrowana względem godziny dwunastej. Godziny nie będą umieszczone dokładnie na obrzeżu tarczy zegara, lecz trochę wewnątrz. Środek elipsy, która jest tarczą zegara nie znajduje się w punkcie (0, 0), musimy więc uwzględnić ten fakt przy obliczaniu współrzędnych godzin. Ponieważ środek tarczy zegara znajduje się w środku okna, promienie elipsy mają odpowiednio wartość ClientRect.Width/2, oraz ClientRect.Height/2, godziny umieścimy na obrzeżu elipsy o mniejszych romieniach.

Do wycentrowania napisów będzie nam potrzebna ich szerokość w pikselach. Szerokość liter nie jest stała, do obliczenia miejsca zajmowanego przez napis posłużymy się metodą MeasureString z klasy Graphics, która zwróci nam między innymi szerokość napisu w pikselach. Metoda ta pobiera jako parametr napis, oraz czcionkę, jaką chcemy go namalować.

Jedna godzina to 30o, więc wykonamy pętlę dwanaście razy zmieniając kąt co 30o. Pętla będzie wykonywana dla zmiennej n zmieniającej się od 1 do 12, ponieważ pierwszą rysujemy godzinę pierwszą, rozpoczniemy od kąta -60o, tak jak pokazano na rys. 5.

0x01 graphic

Rys. 5. Rysowanie godzin na tarczy zegara analogowego

Uzupełnijmy kod dopisując metodę DrawNumbers

Private Sub DrawNumbers(ByVal g As Graphics)

Dim angle As Double

Dim ww As Double

Dim hh As Double

Dim x As Double

Dim y As Double

Dim sc As Double

Dim sh As Double

Dim ss As SizeF

Dim n As Integer

Dim midX As Integer

Dim midY As Integer

Dim s As String

angle = -60.0

For n = 1 To 12

midX = ClientRectangle.Width / 2

midY = ClientRectangle.Height / 2

ww = (ClientRectangle.Width - 50) / 2.0

hh = (ClientRectangle.Height - 50) / 2.0

x = ww * Math.Cos(angle * Math.PI / 180.0)

x = x + midX

y = hh * Math.Sin(angle * Math.PI / 180.0)

y = y + midY

s = Convert.ToString(n)

ss = g.MeasureString(s, Me.Font))

sc = ss.Width / 2

sh = (ss.Height / 2) - 1

g.DrawString(s, Me.Font, Brushes.Black, _

x - sc, y - sh, New StringFormat())

angle = angle + 30

Next

End Sub

Kolejmym krokiem jest zmodyfikowanie metody Paint, tak aby wywołać w niej naszą nowo napisaną metodę DrawNumbers:

Private Sub Form1_Paint(ByVal sender As System.Object, _

ByVal e As System.Windows.Forms.PaintEventArgs) _

Handles MyBase.Paint

Dim g As Graphics = e.Graphics

e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

DrawClock(g)

DrawNumbers(g)

End Sub

Po dokonaniu tych zmian i uruchomieniu naszej aplikacji na ekranie powinniśmy

zobaczyć coś podobnego do widoku zaprezentowanego na rys 6.

0x01 graphic

Rys. 6. Zegar analogowy wygląd aplikacji (tarcza z godzinami)

Wskazówki

Ostatnim krokiem jest namlowanie wskazówek sekundnika, minut, oraz godzin. Możemy malować je w sposób podobny do tego jaki został użyty przy malowaniu godzin. Zacznijmy najpierw od sekundnika, ponieważ pełen obieg wskazówki sekundnika oznacza upływ minuty, sekunda jest 1/60 częścią minuty, wskazówka sekundnika, będzie malowana w 60 różnych położeniach, stopień o jaki należy ją obrócić po upływie sekundy to 360/60 = 6.

Do rysowania wskazówek zastosujemy jednak inną metodę niż zaprezentowaną przy

rysowaniu godzin. Skorzystamy z klasy GraphicsPath, oraz klasy reprezentuj ącej

macierze w przestrzeni dwu wymiarowej Matrix.

Wskazówki potraktujemy jako odcinki o początku w środku tarczy, a współrzędne końca zostaną wyznaczone na podstawie aktualnej godziny, minuty oraz sekundy. Zacznijmy od sekund. Wiemy, że po upływie sekundy wskazówkę musimy obrócić o 6o, czyli jeśli upłynęło np. 15 sekund, to kąt jaki tworzy wskazówka z osią OY naszego układu współrzędnych wynosi 90o. Tak więc, mając punkt p = (x1, y1) możemy obrócić go względem środka układu współrzędnych, a nowe współrzędne punktu po obrocie wyrażają następujące wzory:

0x01 graphic
0x08 graphic

Możemy zapisać powyższy układ równań w postaci macierzowej:

0x01 graphic

gdzie M jest macierzą obrotu. W naszym przypadku

0x01 graphic

Macierz M opisuje obrót punktu względem środka układu współrzdnych. Aby obrócić punkt wokół innego punktu, wystarczy wprowadzić nowy lokalny układ współrzędnych posiadający środek w punkcie względem którego chcemy dokonać obrotu. Sprowadzi się to do przesunięcia (translacji) punktu do środka układu współrz ędnych, dokonania obrotu i ponownego przemieszczenia. Mówiąc krótko, do dokonania złożenia trzech transformacji: translacji, obrotu oraz translacji.

Możemy sobie ułatwić życie i zamiast wyznaczać trzy macierze opisujące translacje oraz obrót skorzystać z z klasy Matrix, posiada ona metodęo nazwie RotateAt, która wyznaczy za nas macierz opisuj ącą obrót względem danego punktu o zadany kąt.

0x01 graphic

Rys. 7. Obrót punktu względem innego punktu

Korzystaj ąc z klasy DataTime, odczytamy bieżącą godzinę, składowe Hour, Minute

oraz Second określają aktualną godzine, minutę oraz sekundę. Znając liczbę sekund,

która upłynęla w bieżącej minucie, możemy policzyć kąt o jaki wskazówka sekundnika

musi zostać obrócona względem położenia pełnej minuty: 0x01 graphic
.

Napiszmy nową metodę o nazwie DrawHands, która na razie będzie rysowała tylko

wskazówkę sekundnika:

Private Sub DrawHands(ByVal g As Graphics)

Dim midX As Integer

Dim midY As Integer

Dim d As DateTime

Dim angles As Double

Dim ps As Point

Dim mTransform As Math.table

Dim gps As GraphicsPath

midX = (ClientRectangle.Left + ClientRectangle.Right) / 2

midY = (ClientRectangle.Top + ClientRectangle.Bottom) / 2

d = DateTime.Now

angles = d.Second * 6.0

mTransform = New Math.table()

mTransform.RotateAt(angles, New PointF(midX, midY))

ps = New Point(midX, 15)

gps = New GraphicsPath()

gps.AddLine(midX, midY, ps.X, ps.Y)

gps.Transform(mTransform)

g.DrawPath(Pens.Red, gps)

End Sub

Najpierw wyznaczamy punkt, względem, którego dokonamy obrotu, jego współrz ędne

to (midX, midY ), czyli środek tarczy zegara. Następnie pobieramy aktualną godzinę, wyznaczamy kąt obrotu, oraz tworzymy nową macierz. Korzystając z metody RotateAt budujemy macierz obrotu o kąt angles względem punktu (midX, midY). Deklarujemy punkt, który będzie obracany, następnie korzystając z klasy GraphicsPath, dokonamy obrotu linii o współrz ędnych pocz ątku (midX, midY ) oraz współrzędnych końca (midX, 15). Przypomnijmy sobie, że układ współrzędnych okna posiada oś OY skierowaną ku dołowi, punkt (midX, 15) leży więc o 15 pikseli od górnej krawędzi okna. Następnie zastosujemy metodę Transform klasy GraphicsPath, która zastosuje transformację opisaną przez macierz mTransform do wszystkich elementów zawartych w GraphicsPath. W naszym przypadku ponieważ zawiera ona tylko jedną linię, dokona obrotu tylko tej jednejłinii. Na zakończenie skorzystamy z metody DrawPath klasy Graphics aby namalować zawartość GraphicsPath.

Visual 6.doc 6/15

Obiekt

Opis

Brush

używany do wypełniania zamkniętych obszarów kolorem, wzorem lub mapą bitową

Pen

używany do rysowania linii, wielokątów, łuków

i innych kształtów

Font

opisuje czcionkę użytą do namalowania napisu

Color

używany do opisu koloru w GDI+

Styl

Opis

Bold

tekst pogrubiony

Italic

tekst pochylony

Regular

tekst normalny

Strikeout

tekst przekreślony

Underline

tekst podkreślony



Klasa

Opis

Bitmap, Image

mapa bitowa i obraz

Brush, Brushes

pędzel służący do malowania wypełnionych figur

Font, FontFamily

klasa reprezentująca czcionki

Graphics

klasa reprezentująca urządzenie graficzne i dostarczająca metod służących do rysowania

Pen

klasa reprezentująca pióro służące do malowania linii oraz krzywych

SolidBrush

klasa reprezentująca pędzel do malowania

figur wypełnionych jednolitym kolorem



Wyszukiwarka

Podobne podstrony:
Lab 2 Visual Analyser oraz kompresje v2
ASP NET 2 0 Tworzenie witryn internetowych z wykorzystaniem C i Visual Basica aspntw
Visual Basic Przykładowe zadania , Studia i nauka, Visual Basic
Visual1
Programowanie w Visual?sic dla Excel
Visual?sic lekacje
Lab6, Visual Basic Lab 6a, Visual Basic Lab 3
Leksykon VISUAL BASIC, r00-05, Rozdział X
MS Visual C Ćwiczenia
Visual Basic Zdarzenia , Studia i nauka, Visual Basic
67 Audio and Visual System
adudczak visualvm
Visual 5
Visualization Exercises
Visual3
visual methodologies chapter4 content analysis pages 1 5

więcej podobnych podstron