Sunteți pe pagina 1din 11

A DELPHI GARAFIKA ALAPJAI

ALAPESETEK

Az egyik leglátványosabb része a programozásnak a grafikus fejlesztés. A grafikában


két alapkoncepció létezik:

1. BITMAP: Bittérképes grafika, ahol a képfelület (rajzlap) minden egyes pontját


(pixelét) egyenként kezeljük. Többnyire fotók és bonyolult rajzok tárolására
szolgálnak. Ilyen alapon épülnek fel a fénykép feldolgozó és retusáló
programok: PaintBrush, Adobe PhotoShop.
Előnyük: a gyors és egyszerű megjelenítés; nem igényelnek különösebb
előfeldolgozást.
Hátrányuk: a viszonylag nagy grafikus fájlméret, hiszen a teljes grafikus
felületet – annak minden pixelét – tárolni kell.

2. VEKTORGRAFIKA: A rajzfelületen ábrázolt – többnyire egyszerű


geometriájú vonalas ábrák kezelésére szolgál. Ilyen programok a mérnöki
tervezésre használt CAD programok, ill. a reklámgrafikai tervezők: AutoCAD,
CorelDraw.
Előnyük: a kisebb fájlméret, hiszen csak az egyes grafikus objektumok
jellemzőit szükséges tárolni. További előny a rugalmas geometriai
transzformálhatóság: nagyítás, eltolás, elforgatás, tükrözés, átméretezhetőség,..
Hátrányuk: Speciális értelmező, feldolgozó programokat ill. előfeldolgozást
igényelnek.

3. KOMBINÁLT RASZTER-VEKTOR GRAFIKÁK: Gyakran a két előbbi


alapeset kombinációja is szerepel a grafikus palettán. A ényképek, mint bitmap
képek szolgáltatják a hátteret, melyen egyszerű vonalas ábrák tünnek fel.
Gondoljunk arra az egyszerű oktató programra, mely az emberi szervezetet
mutatja: az egérrel mozogra az ábrán rendre kiírja az alatta található szerv
nevét és egyéb adatait.
Ergó: a két alapvető grafikai rendszer előnyeit egyesíti ez a kombinált grafikai
módszer.
TImage komponens

A Delphi alapesetben 2 grafikus komponenssel szolgál a rajzok ill. képek


megjelenítésére: TImage ill. TPaintBox.

A TImage grafikus képek megjelenítésére szolgál. A TPicture objektum a kép


tárolására szolgál: az aktuális bitmap, icon, metafile, vagy egyéb graphika, melyet a TImage
megjelenít. Számos tulajdonsága a kép megjelenítésének jellegét szabályozza.

KÉP BETÖLTÉSE:

Tervezési időben: A VCL (Visual Component Librarry) komponenspaletta Additional


lapjáról válasszuk ki a TImage component és helyezzük el egy üres form-on. Ha egérrel
kétszer ráklikkelünk akkor megnyílik egy dialógus ablak mely grafikus kép betöltésére
szolgál.

A betöltött kép eredeti méretben jelenik meg a TImage felületen. Ha azt szeretnénk,
hogy a grafikus felület automatikusan a betöltött kép méretét felvegye, akkor az AutoSize
tulajdonságnak True (igaz) értéket kell adni. Ilyenkor a kép már nem átméretezhető.
Ha viszont a kép méretét akarjuk változtatni –
kicsinyíteni/nagyítani -, akkor az AutoSize=False és a
Stretch=True értékeket kell az Object Inspector-ban beállítani.
A Stretch paraméter igaz értéke mellett a TImage méretét
változtatva, a bennfoglalt kép a teljes felületet automatikusan
kitölti, alkalmazkodik a képkeret változásaihoz.
VEKTOR GRAFIKA
A Canvas = rajzfelület grafika tárolására szolgál bitmap formátumban, azaz minden
egyes képpont egy-egy pixelnyi adat. Ilyen értelemben pl. egy 100x100 pixel méretű grafika
1000 adattal írható le. Egy fénykép vagy nagyon bonyolult rajz esetén nincs más
választásunk: a teljes bitmap grafikát mentenünk kell.

Image1.Picture.SaveToFile(fájlnév);

Azonban egyszerű geometrai jellemzőkkel megadható vonalas ábrák tárolásának vagy


egy helykímélőbb megoldása is, amennyiben csak a geometriai rajzobjektumok jellemzőit
tároljuk. Pl. egy szakaszt a két végpontja jellemez: (x1;y1)-(x2;y2). Ez négy adat, azért egy
ilyen egyszerű rajzot nem érdemes pixelenként tárolni, elegendő a rajzi objektum jellemzőit
elmenteni, amiből egy megfelelő program bármikor reprodukálni tudja az eredeti rajzot.

1. Feladat: RAJZOLO - Készítsünk egy PaintBrush-hoz hasonló rajzoló


programot, melyből a rajz bitmap és vektorgrafikus formátumban is
menthető.

Legyen a program kissé lebutított változatában csak 3 rajz objektum szerkesztési lehetőség:
Szakasz; Négyszög és Ellipszis. A rajzelemeket tároljuk a memóriában és menthető ill.
betölthető legyen.
ADATTÁROLÁS: Az egyes rajzi objektumokat a befoglaló téglalapjuk két átellenes
sarkának koordinátáival fogjuk jellemezni.

1 2 3

Mindhárom objektum tárolása azonos szerkezetű rekordokban történhet:

TRajzObjektum = record
Tipus : integer; // Tipus: 1=szakasz; 2=négyszög; 3=ellipszis
P1,P2 : TPoint; // A befoglaló téglalap sarokpontjai;
End;
A recordok tárolására számtalan módszer alkalmas:

1. Tömbben: Alakzatok : Array[0..100] of TRajzObjektum;


2. Dinamikus tömbben: Alakzatok : Array of TRajzObjektum;
3. TList objektumban: Magasan szervezett lista objektum.
4. Memória stream-en: A memória folyamon nagyszámú objektum tárolható.

A mintaprogram segítségével egyszerű vektorgrafika készíthető és menthető, betölthető. A


színpaletta a rajztoll színét, az alatta lévő SpinEdit (Samples lapról) a toll vastagságát állítja.
unit Rajzolo1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
ExtCtrls, Buttons, StdCtrls, Spin, ColorGrd;

type
TRajzmod = (rNone, rSzakasz, rNegyszog, rKor);

TRajzObjektum = packed record


Tipus : TRajzmod; // Tipus: 1=szakasz; 2=négyszög;
3=ellipszis
P1,P2 : TPoint; // A befoglaló téglalap sarokpontjai;
szin : TColor;
Vastagsag : integer;
End;

TForm1 = class(TForm)
Panel1: TPanel;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
SpeedButton4: TSpeedButton;
SpeedButton5: TSpeedButton;
SpeedButton6: TSpeedButton;
Image1: TImage;
SpeedButton7: TSpeedButton;
SpeedButton8: TSpeedButton;
SpeedButton9: TSpeedButton;
ColorGrid1: TColorGrid;
SpinEdit1: TSpinEdit;
OpenDialog1: TOpenDialog;
procedure FormCreate(Sender: TObject);
procedure SpeedButton7Click(Sender: TObject);
procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SpeedButton8Click(Sender: TObject);
procedure SpeedButton9Click(Sender: TObject);
procedure ColorGrid1Change(Sender: TObject);
procedure SpinEdit1Change(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
private
Rajzmod: TRajzmod;
kezdoPont, VegPont : TPoint;
AlakzatSzam: integer;
Alakzatok : Array[0..100] of TRajzObjektum;
public
procedure Rajzolas(Rajzmod: TRajzmod; P1,P2: TPoint);
procedure Cls;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);


begin
Rajzmod := rNone;
AlakzatSzam:=0;
DoubleBuffered := True;
Cls;
end;

// Képfelület törlése fehér színnel


procedure TForm1.Cls;
begin
with Image1.Canvas do begin
Brush.Color := clWhite;
Brush.Style := bsSolid;
FillRect(Cliprect);
end;
end;

// Rajzoló rutin
procedure TForm1.Rajzolas(Rajzmod: TRajzmod; P1, P2: TPoint);
begin
Case Rajzmod of
rSzakasz : begin
Image1.Canvas.MoveTo(P1.X,P1.Y);
Image1.Canvas.LineTo(P2.X,P2.Y);
end;
rNegyszog: Image1.Canvas.Rectangle(P1.X,P1.Y,P2.X,P2.Y);
rKor : Image1.Canvas.Ellipse(P1.X,P1.Y,P2.X,P2.Y);
end;
end;

procedure TForm1.SpeedButton7Click(Sender: TObject);


begin
Rajzmod := TRajzmod(ord(TComponent(Sender).Tag))
end;

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;


Shift: TShiftState; X, Y: Integer);
begin
kezdoPont := Point(x,y);
VegPont := Point(x,y);
end;

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,


Y: Integer);
begin
if Shift = [ssLeft]then begin
Image1.Canvas.Pen.Mode := pmNotXor;
Rajzolas(Rajzmod,kezdoPont,VegPont);
Image1.Canvas.Pen.Mode := pmNotXor;
Rajzolas(Rajzmod,kezdoPont,Point(x,y));
vegPont := Point(x,y);
end;
end;
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
with Alakzatok[AlakzatSzam] do begin
Tipus := Rajzmod;
p1 := kezdoPont;
p2 := VegPont;
szin := Image1.Canvas.Pen.Color;
vastagsag := Image1.Canvas.Pen.width;
end;
Inc(AlakzatSzam);
end;

procedure TForm1.SpeedButton8Click(Sender: TObject);


begin
Cls;
end;

procedure TForm1.SpeedButton9Click(Sender: TObject);


var i: integer;
pen : TPen;
begin
// Grafika ujrarajzolása
Pen := Image1.Canvas.Pen;
for i:=0 to AlakzatSzam-1 do begin
Image1.Canvas.Pen.Color := Alakzatok[i].szin;
Image1.Canvas.Pen.Width := Alakzatok[i].Vastagsag;
Rajzolas(Alakzatok[i].Tipus,Alakzatok[i].p1,Alakzatok[i].p2);
end;
Image1.Canvas.Pen := Pen;
end;

procedure TForm1.ColorGrid1Change(Sender: TObject);


begin
// A rajztoll színének megváltoztatása
Image1.Canvas.Pen.Color := ColorGrid1.ForegroundColor;
end;

procedure TForm1.SpinEdit1Change(Sender: TObject);


begin
Image1.Canvas.Pen.Width := SpinEdit1.Value;
end;

// Rajz betöltése
procedure TForm1.SpeedButton2Click(Sender: TObject);
var i: integer;
f: file;
err: integer;
begin
if OpenDialog1.Execute then
Try
Rajzmod := rNone;
AssignFile(f,OpenDialog1.Filename);
Reset(f);
AlakzatSzam := -1;
repeat
Inc(AlakzatSzam);
BlockRead(f,Alakzatok[AlakzatSzam],SizeOf(TRajzObjektum),err);
until (err=0) or (err<>SizeOf(TRajzObjektum));
finally
CloseFile(f);
cls;
SpeedButton9Click(Sender);
end;
end;

// Rajz mentése
procedure TForm1.SpeedButton3Click(Sender: TObject);
var i: integer;
f: file;
err: integer;
begin
if OpenDialog1.Execute then
Try
AssignFile(f,OpenDialog1.Filename);
Rewrite(f);
for i:=0 to AlakzatSzam-1 do begin
BlockWrite(f,Alakzatok[i],SizeOf(TRajzObjektum),err);
end;
finally
CloseFile(f);
end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);


begin
Cls;
AlakzatSzam:=0;
end;

end.
Érdemes elemezni az iménti programot, mert számtalan hasznos megoldást tartalmaz.

GUMISZÁL TECHNIKA: A szerkesztés során pl. egy szakasz megrajzolásakor ki kell


jelölnünk a szakasz egyik végpontját bal egérgombbal a rajzlapra klikkelve (MouseDown),
majd lenyomott gombbal mintegy gumiszálat feszítve elmozgatjuk a másik végpontot a
végleges helyére (MouseMove).
Amikor felengedjük a gombot, a grafika letárolásra kerül(MouseUp).

A gumiszál oly módon valósítható meg, hogy a toll rajzolási módját pmNotXor-ra állítjuk,
ilyenkor az első rajzolás megjelenik, de a második rárajzolás már törli az eredeti rajzot.
Esetünkben a szakasz nyujtásakor az eredeti vonalat törölni kell, az újat meg megrajzolni.
Eközben a végpont változik, a kezdőpont viszont rögzített.

if Shift = [ssLeft]then begin


Image1.Canvas.Pen.Mode := pmNotXor;
Rajzolas(Rajzmod,kezdoPont,VegPont);
Image1.Canvas.Pen.Mode := pmNotXor;
Rajzolas(Rajzmod,kezdoPont,Point(x,y));
vegPont := Point(x,y);
end;

A Rajzolas nevű eljárás egyben letudja a grafikus objektumok megrajzolását a Rajzmod


függvényében.
2. FELADAT: RAJZEDITOR: Fejlesszük eredeti programunkat oly módon,
hogy a már megrajzolt grafikus objektumokat ki lehessen jelölni és át
lehessen utólag alakítani.

Programunk nagy fejlődésen megy át ez által, hiszen egy rajzi elem tetszőlegesen
módosíthatóvá válik.

KIVÁLASZTÁSI ELJÁRÁS:

Első lépésként meg kell oldanunk egy grafikus objektum kijelölését. Ezzel jelezzük azon
szándékunkat, hogy ezzel az objektummal további célunk van: módosítani szeretnénk.

Ehhez, először is az adatrekordot kell bővítenünk egy Kivalasztott logikai mezővel. Ha ez a


mező True (igaz) értéket vesz fel, akkor módosítható lesz. A rajzon ez úgy jelenik meg, hogy
a befoglaló téglalap szaggatott vonallal kirajzolásra kerül, sarokpontjait kék négyszetek jelzik.
Ezen sarokpontok lenyomott egérgombbal elmozgathatóvá válnak.

S-ar putea să vă placă și