Grafika a Delphiben

Download Report

Transcript Grafika a Delphiben

Grafika a programban

Készítette: Pető László

Bevezetés

• Valójában nem a célobjektumra rajzolunk, hanem annak festővászon területére (

canvas

).

• Csak olyan objektumra tudunk rajzolni, amelynek van canvas tulajdonsága.

• A canvas is egy objektum saját tulajdonságokkal és eljárásokkal.

Canvas

• A Canvas objektum legfontosabb tulajdonságai: –

Pen:

(toll) vonalrajzoláshoz –

Brush:

(ecset) alakzatok kitöltésére –

Font:

(betűtípus) szöveg írásához –

Pixels:

(képponttömb) ez tartalmazza magát a képet.

• A Canvas csak futás közben érhető el, ezért grafikus programokhoz, mindenképp kódot kell írni.

Célok

• A toll, az ecset és a képponttömb használata.

• Egyszerű grafikai alkalmazás készítése, amely képes: – Rajzolásra egér segítségével – Eszköztára van – A toll és ecset beállítására – Állapotsort használ – Bittérképes grafika módosítására.

– Nyomtatásra – Vágólapkezelésre

A képponttömb kezelése

• Minden canvas rendelkezik egy pixels tömbbel, amely a canvas pontjainak a színét tartalmazza.

• A pontok egyenként is színezhetők, de ehhez célszerűbb a pen és a brush használata.

• A canvas (0,0) pontja a bal felső sarok. Az első szám az ettől vízszintesen, a második az ettől függőlegesen mért távolságot jelenti pixelben.

A képponttömb használata

• Az (

x

,

y

) pont színének lekérdezése: – valtozo:=canvas.pixels[x,y]; • Az (

x

,

y

) pont színének beállítása: – canvas.pixels[x,y]:=szinkod; • A színkódokkal már foglalkoztunk.

– Clred, clblue, clwhite, stb. RGB függvény.

1. program

• Készítsünk programot, amely kirajzol egy téglalapot a (20, 20) és (320, 120) pontok által meghatározott átlók közé zöld színnel.

• A téglalapon kívüli terület fehér legyen.

• Ha az ablakra kattintunk, írja ki a program annak a képpontnak a színét, amelyre kattintottunk.

• procedure TForm1.Sznez1Click(Sender: TObject); • var i,j:integer; • begin • for i:=0 to clientwidth do • for j:=0 to clientheight do • if (i>=20) and (i<=320) and (j>=20) and (j<=120) then • canvas.Pixels[i,j]:=clgreen else canvas.Pixels[i,j]:=clwhite; • end;

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • if canvas.Pixels[x,y]=clgreen then • showmessage('A képpont színe zöld') else • showmessage('A képpont színe fehér'); • end;

A toll használata

• A Canvas Pen tulajdonságával lehet rajzolni • Jellemzői: –

Color:

Szín –

Width:

Vonalvastagság –

Style:

Vonaltípus. (folytonos, pontozott, – szaggatott, stb.)

Mode:

Felülírás módja. Hogyan kombinálódjon a szín a már meglévőkkel.

A toll

• Alapértelmezés szerint a toll fekete színű, egy pixel vastagságú folytonos vonalat rajzol, a felülírási mód

pmCopy

, tehát felülír mindent.

• A toll aktuális pozícióját a Canvas

penpos

tulajdonsága tárolja.

MoveTo, LineTo

• MoveTo(x,y) : a toll pozíciója az x,y koordinátájú pont lesz rajzolás nélkül.

• LineTo(x,y) : a toll az aktuális pozíciótól az x,y koordinátájú pontig vonalat rajzol. A rajzolás végén az x,y lesz a toll pozíciója.

2. program

• Készítsünk olyan programot, amely bekéri a kezdőpont és a végpont koordinátáit, majd közöttük vonalat rajzol!

• procedure TForm1.Button1Click(Sender: TObject); • var kx,ky,vx,vy:integer; • begin • kx:=strtoint(edit1.text); • ky:=strtoint(edit2.text); • vx:=strtoint(edit3.text); • vy:=strtoint(edit4.text); • canvas.MoveTo(kx,ky); • canvas.LineTo(vx,vy); • end;

Az ecset (brush)

• Nagyobb területek kitöltésének a módját határozza meg.

• Tulajdonságai: –

Color

: Szín –

Style

: az ecset milyen kitöltőmintát használjon, milyen kölcsönhatásban az eredeti színekkel.

Bitmap

: egy 8X8-as képet lehet megadni, amit kitöltőmintaként használhatunk.

Az ecset (brush)

• Alapértelmezésként az ecset színe fehér, a terület minden pontját egyformán színezi, nem használ képet kitöltőmintaként.

Speciális sokszögek rajzolása

• Ötféle síkidomot rajzolhatunk: – Téglalapot – Ellipszist – Lekerekített sarkú téglalapot – Sokszöget – egyéb speciális alakzatokat

Téglalap rajzolása

• Rectangle(X1,Y1,X2,Y2); • X1,Y1 : az átló kezdőpontjának koordinátái • X2,Y2 : az átló végpontjának koordinátái

Ellipszis rajzolása

• Ellipse(X1,Y1,X2,Y2); • X1,Y1 : az ellipszist érintő téglalap átlójának kezdőpontja • X2,Y2 : az ellipszist érintő téglalap átlójának végpontja

3. program

• Készítsünk programot, amely a megfelelő paraméterek bejuttatása után téglalapot, vagy ellipszist rajzol!

• procedure TForm1.Button1Click(Sender: TObject); • var kx,ky,vx,vy:integer; • begin • kx:=strtoint(edit1.text); • ky:=strtoint(edit2.text); • vx:=strtoint(edit3.text); • vy:=strtoint(edit4.text); • canvas.Rectangle(kx,ky,vx,vy); • end;

• procedure TForm1.Button2Click(Sender: TObject); • var kx,ky,vx,vy:integer; • begin • kx:=strtoint(edit1.text); • ky:=strtoint(edit2.text); • vx:=strtoint(edit3.text); • vy:=strtoint(edit4.text); • canvas.Ellipse(kx,ky,vx,vy); • end;

Lekerekített téglalap

• RoundRect(x1,y1,x2,y2,a,b); • x1,y1 : az átló kezdőpontja • x2,y2 : az átló végpontja • a,b : a lekerekítéshez használt ellipszis kis és nagytengelye

Sokszögek rajzolása

• Polygon([point(x1,y1),point(x2,y2),…,point (xn,yn)]); • xi,yi : a sokszög csúcspontja

Speciális alakzatok

• A canvas objektum további alakzatok rajzolására is tartalmaz metódusokat: – körív – körszelet – stb.

Az egérhez kapcsolódó események

• Négy alapvető eseményt különböztetünk meg: – az egérgomb lenyomása (

onMouseDown

) – az egérgomb felengedése (

onMouseUp

) – az egér mozgatása (

onMouseMove

) – kattintás (

onClick

)

onMouseDown, onMouseUp, onMouseMove

• Paraméterek: –

Sender

: Az eseményt észlelő objektum –

Button

: a lenyomott egérgomb: mbLeft, mbMiddle, mbRight –

Shift

: az esemény pillanatában lenyomva tartott váltóbillentyűk : ALT, CTRL, SHIFT –

X, Y

: az egérmutató pozíciója az esemény bekövetkeztekor.

4. program

• Készítsünk programot, amely kattintásra kiírja az egérmutató pozícióját!

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.TextOut(x,y,inttostr(x)+', '+inttostr(y)); • end;

5. program

• Készítsünk programot, amely az egérkurzor lenyomásának pozíciójától az egérgomb felengedésének pozíciójáig rajzol egy szakaszt!

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.MoveTo(x,y); • end;

• procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.LineTo(x,y); • end;

!!!!!

• A vonal sajnos csak az egérgomb felengedésekor válik láthatóvá.

• Javítsuk a hibát!

6. program

• Javítsuk ki úgy a programot, hogy a mozgatás közben is lehessen látni az egér mozgását!

• procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, • Y: Integer); • begin • canvas.LineTo(x,y); • end;

!!!!!

• A programmal szabadkézi rajz készíthető, de akkor is rajzol, ha az egérgomb nincs lenyomva.

• A gomb lenyomásának vizsgálatához vegyünk fel egy rajzolhat logikai változót.

• A programnak csak akkor kéne rajzolnia, ha ez igaz értéket tartalmaz.

7. program

• Javítsuk ki az előbbi programot úgy, hogy csak lenyomott gomb esetén rajzoljon!

• • public { Public declarations } • rajzolhat:boolean; • end;

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • rajzolhat:=true; • canvas.MoveTo(x,y); • end;

• procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.LineTo(x,y); • rajzolhat:=false; • end;

• procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, • Y: Integer); • begin • if rajzolhat then canvas.LineTo(x,y); • end;

!!!!!

• A program szabadkézi rajzhoz már jó.

• Ha azonban vonalzót szeretnénk, akkor az a probléma, hogy a LineTo metódus mindig megváltoztatja a toll pozícióját.

• A kezdeti állapotot tehát meg kell különböztetni a közbenső állapotoktól.

• Vegyünk fel egy kezdx és egy kezdy egész típusú változót!

8. program

• Készítsünk programot, amely az egér lenyomott gombjával nem szabadkézi rajzot, hanem szakaszt rajzol a lenyomási és a fölengedési pozíció között!

• • • • public { Public declarations } rajzolhat:boolean; kezdx,kezdy:integer; • end;

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • rajzolhat:=true; • canvas.MoveTo(x,y); • kezdx:=x; • kezdy:=y; • end;

• procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.MoveTo(kezdx,kezdy); • canvas.LineTo(x,y); • rajzolhat:=false; • end;

• procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, • Y: Integer); • begin • if rajzolhat then • begin • canvas.MoveTo(kezdx,kezdy); • canvas.LineTo(x,y); • end; • end;

!!!!!

• A vonal elkészül, de sajnos a közbenső vonalak is ott maradnak. (Persze effektnek nem is olyan rosszak! :)) • A korábbi szakaszt mindig törölni kéne.

• Ehhez a korábbi szakasz végpontját is el kéne tárolni vegx, vegy egész változókban.

9. program

• Készítsünk olyan programot, ahol csak a lenyomási pozíció és a felengedési pozíció között jelenik meg vonal!

• • • • public { Public declarations } rajzolhat:boolean; kezdx,kezdy:integer; • vegx,vegy:integer; • end;

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • rajzolhat:=true; • canvas.MoveTo(x,y); • kezdx:=x; • kezdy:=y; • vegx:=x; • vegy:=y; • end;

• procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • canvas.MoveTo(kezdx,kezdy); • canvas.LineTo(x,y); • rajzolhat:=false; • end;

• • • • • • procedure TForm1.FormMouseMove(Sende r: TObject; Shift: TShiftState; X, • Y: Integer); • begin • • • • • if rajzolhat then begin //a régi szakasz törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.LineTo(vegx,vegy); //az új szakasz canvas.MoveTo(kezdx,kezdy); canvas.LineTo(x,y); end; • • vegx:=x; vegy:=y; • canvas.pen.Mode:=pmCopy; • end;

!!!!!

• A pmNotXor állapotú toll törli azokat a képpontokat amelyek nem háttérszínűek, és tollszínűvé teszi őket, ha háttérszínűek voltak.

• A pmCopy állapotú toll mindig rajzol. (Ez az alapértelmezett toll állapot) • Szabadkézi rajzon és vonalzón kívül ellipszist és téglalapot is szeretnénk rajzolni.

• Ennek az eldöntéséhez eszköztárra van szükség.

Eszköztár a programban

• Az eszköztár olyan panel, amely gyorsítógombokat tartalmaz.

• A gyorsítógombok olyan parancsgombok, amelyekben a felirat helyett többnyire egy kis kép látható.

• Készítsünk 30X30-as bitképeket a gyorsítógombokra! (szabadkézi rajz, vonalzó, téglalap, ellipszis; toll, ecset)

Elkészítés

• Helyezzünk a főablakra egy Panel komponenst!

• Töröljük a Caption tulajdonság értékét!

• Igazítsuk az ablak tetejére! (align=alTop) • A panel magassága 32 képpont legyen! (height=32) • Helyezzünk gyorsítógombokat a panelre! 4 2-es csoportosításban!

Elkészítés

• A gyorsítógombok szélessége és magassága a bitképeknek megfelelően 30 képpont legyen!

• A top értéket állítsuk 1-re, így a gomb a panelnak pont a közepére fog kerülni.

• Állítsuk be a gombokon látható képeket a megfelelő bitképek segítségével! (glyph)

Csoportokba szervezés

• A csoportokon belül, ha egy gomb be van kapcsolva, akkor ugyanebben a csoportban másik ne lehessen ugyanilyen állapotban.

• Az első négy gomb groupindex tulajdonsága legyen 1, a tollé 2, az ecseté 3!

• A tollnak és az ecsetnek kikapcsolhatónak is kell lennie allowallup=true

Kezdeti beállítások

• A gombok kezdeti állapota a Down tulajdonsággal szabályozható.

• Ha ez true, akkor a gomb be van kapcsolva, ha false, akkor ki van kapcsolva.

• A szabadkézi rajz gombja legyen alapértelmezett állapotban lenyomva!

Különböző rajzeszközök használata

• A programnak mindig tudnia kell, hogy a felhasználó melyik eszközt választotta.

• Ehhez vezessünk be egy rajzeszk egész változót, amelynek 1 az értéke szabadkézi rajz esetén, 2 vonal, 3 téglalap, 4 ellipszis esetén!

• • • • public { Public declarations } rajzolhat:boolean; kezdx,kezdy:integer; • • vegx,vegy:integer; rajzeszk:integer; • end;

• procedure TForm1.SpeedButton1Click(Sender: TObject); • begin • rajzeszk:=1; • end;

• procedure TForm1.SpeedButton2Click(Sender: TObject); • begin • rajzeszk:=2; • end;

• procedure TForm1.SpeedButton3Click(Sender: TObject); • begin • rajzeszk:=3; • end;

• procedure TForm1.SpeedButton4Click(Sender: TObject); • begin • rajzeszk:=4; • end;

• procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • rajzolhat:=true; • canvas.MoveTo(x,y); • kezdx:=x; • kezdy:=y; • vegx:=x; • vegy:=y; • end; 

1

• • • procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • • • case rajzeszk of 1:begin canvas.LineTo(x,y); rajzolhat:=false; end;

• • • • • • • • • •

2

2:begin canvas.MoveTo(kezdx,kezdy); canvas.LineTo(x,y); rajzolhat:=false; end; 3:begin canvas.MoveTo(kezdx,kezdy); canvas.rectangle(kezdx,kezdy,x,y); rajzolhat:=false; end;

3

• • • • 4:begin canvas.MoveTo(kezdx,kezdy); canvas.ellipse(kezdx,kezdy,x,y); rajzolhat:=false; • end; • end; • • end; 

1

• procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, • Y: Integer); • begin • case rajzeszk of • 1:begin • if rajzolhat then canvas.LineTo(x,y); • end;

• • • • • • • • • • • 2:begin if rajzolhat then

2

begin //a régi szakasz törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.LineTo(vegx,vegy); //az új szakasz canvas.MoveTo(kezdx,kezdy); canvas.LineTo(x,y); end;

3

• • vegx:=x; vegy:=y; • canvas.pen.Mode:=pmCopy; • end;

• • • • • • • • • • • 3:begin if rajzolhat then

4

begin //a régi téglalap törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.rectangle(kezdx,kezdy,vegx,vegy); //az új téglalap canvas.MoveTo(kezdx,kezdy); canvas.rectangle(kezdx,kezdy,x,y); end;

5

• • vegx:=x; vegy:=y; • canvas.pen.Mode:=pmCopy; • end;

• • • • • • • • • • • 4:begin if rajzolhat then

6

begin //a régi ellipszis törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.ellipse(kezdx,kezdy,vegx,vegy); //az új ellipszis canvas.MoveTo(kezdx,kezdy); canvas.ellipse(kezdx,kezdy,x,y); end;

7

• • vegx:=x; vegy:=y; • canvas.pen.Mode:=pmCopy; • end; • end; • • end; 

!!!!!

• Az indításkor hiába van lenyomva a szabadkézi rajz gombja, a program nem rajzol.

• Javítsuk ki!

• A rajzeszk kezdeti értéke 1 legyen!

• procedure TForm1.FormCreate(Sender: TObject); • begin • rajzeszk:=1; • end;

A toll és az ecset beállításai

• Rejtett eszköztár létrehozása • Az eszköztár ki- és bekapcsolása • A toll stílusának módosítása • A toll színének módosítása • A toll vastagságának módosítása • Az ecset stílusának módosítása • Az ecset színének módosítása

Rejtett eszköztár létrehozása

• Hozzuk létre a TollEszkoztar és EcsetEszkoztar nevű eszköztárakat.

• Mindegyikhez egy-egy panelt használjunk!

Toll eszköztár

• Gyorsítógombok (groupindex=4, a legfölsőnél down=true) • Label (ez fogja mutatni az aktuális vonalvastagságot) • ColorGrid (ennek a méreteit a height, és width tulajdonsággal szabályozhatjuk; GridOrdering=go2x8; BackgroundEnabled=false) • Scrollbar (a vonalvastagság szabályozásához, min=1; max=40)

Ecset eszköztár

• Gyorsítógombok (groupindex=5, a legfölsőnél down=true) • ColorGrid (ennek a méreteit a height, és width tulajdonsággal szabályozhatjuk; GridOrdering=go2x8; BackgroundEnabled=false)

Az eszköztárak elrejtése

• A toll és ecset eszköztáraknak induláskor kikapcsolt állapotban kell lennie. (A komponensek visible tulajdonságát false-ra kell állítani!) • A ki- és bekapcsolás a fő eszköztár megfelelő gombjával történik majd, ezeknek meg kell írni az onclick eljárását.

• procedure TForm1.SpeedButton5Click(Sender: TObject); • begin • tolleszkoztar.Visible:=speedbutton5.Down; • end; • procedure TForm1.SpeedButton6Click(Sender: TObject); • begin • ecseteszkoztar.Visible:=speedbutton6.Down; • end;

A toll szabályozása

• A vonalstílus beállításához hozzunk létre egy saját eljárást Vonalstilus néven.

• Ne felejtsük el külön deklarálni a program eljárásai között!!!

• A végén az eljárást minden vonalstílust módosító gombhoz rendeljük hozzá! (onClick)

• procedure TForm1.Vonalstilus(Sender: TObject); • begin • • if Sender=speedbutton7 then canvas.pen.style:=psSolid else if Sender=speedbutton8 then canvas.pen.style:= psDash //szaggatott • else if Sender=speedbutton9 then canvas.pen.style:=psDot //pontozott • else if Sender=speedbutton10 then canvas.pen.style:= psDashDot • else if Sender=speedbutton11 then canvas.pen.style:= psDashDotDot • else if Sender=speedbutton12 then canvas.pen.style:= psClear;//törlő • end;

A toll színének beállítása

• procedure TForm1.ColorGrid1Click(Sender: TObject); • begin • canvas.pen.Color:= colorgrid1.ForegroundColor; • end;

A vonalvastagság beállítása

• procedure TForm1.ScrollBar1Change(Sender: TObject); • begin • canvas.pen.Width:=scrollbar1.Position; • label1.Caption:= inttostr(scrollbar1.position); • • end; Megjegyzés: A vonalstílus csak 1-es vonalméret esetén használható

Az ecset szabályozása

• Az ecset beállításához hozzunk létre egy saját eljárást Ecsetstilus néven.

• Ne felejtsük el külön deklarálni a program eljárásai között!!!

• A végén minden ecsetbeállító gomb onclick eljárásához ezt az eljárást rendeljük hozzá

• • • • • procedure TForm1.Ecsetstilus(Sender: TObject); • begin if sender=speedbutton13 then canvas.Brush.Style:=bssolid else if sender=speedbutton14 then canvas.Brush.Style:=bsclear else if sender=speedbutton15 then canvas.Brush.Style:=bshorizontal else if sender=speedbutton16 then canvas.Brush.Style:=bsvertical • • • • else if sender=speedbutton17 then canvas.Brush.Style:=bsfdiagonal else if sender=speedbutton18 then canvas.Brush.Style:=bsbdiagonal else if sender=speedbutton19 then canvas.Brush.Style:=bscross else if sender=speedbutton20 then canvas.Brush.Style:=bsdiagcross; • end;

Az ecset színe

• procedure TForm1.ColorGrid2Click(Sender: TObject); • begin • canvas.Brush.Color:= • colorgrid2.ForegroundColor; • end;

Állapotsor készítése

• Helyezzünk egy Panel komponenst az ablakra, nevezzük allapotsor-nak.

• Align tulajdonságát állítsuk alBottom-ra • A Caption tulajdonságát töröljük!

Állapotsor

• Helyezzünk két további panelt az állapotsorra (Kezdopoz, Aktualispoz) • Az egyiket igazítsuk balra, a másikat a maradék területhez (alClient) • A bevelinner és borderwidth tulajdonságok állításával 3D effektusokat állíthatunk

• • procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); • begin • rajzolhat:=true; • canvas.MoveTo(x,y); • kezdx:=x; • kezdy:=y; • vegx:=x; • vegy:=y; • kezdopoz.caption:='Kezdőpont: '+inttostr(x)+', '+inttostr(y); • end;

• • procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, • Y: Integer); • begin • case rajzeszk of • 1:begin • if rajzolhat then canvas.LineTo(x,y); • end;

• • • • • • • • • • • • • • • • 2:begin if rajzolhat then begin //a régi szakasz törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.LineTo(vegx,vegy); //az új szakasz canvas.MoveTo(kezdx,kezdy); canvas.LineTo(x,y); end; vegx:=x; vegy:=y; canvas.pen.Mode:=pmCopy; end;

• • • • • • • • • • • • • • • 3:begin if rajzolhat then begin //a régi téglalap törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.rectangle(kezdx,kezdy,vegx,vegy); //az új téglalap canvas.MoveTo(kezdx,kezdy); canvas.rectangle(kezdx,kezdy,x,y); end; vegx:=x; vegy:=y; canvas.pen.Mode:=pmCopy; end;

• • • • • • • • • • • • • • • 4:begin if rajzolhat then begin //a régi ellipszis törlése canvas.Pen.Mode:=pmNotXor; canvas.MoveTo(kezdx,kezdy); canvas.ellipse(kezdx,kezdy,vegx,vegy); //az új ellipszis canvas.MoveTo(kezdx,kezdy); canvas.ellipse(kezdx,kezdy,x,y); end; vegx:=x; vegy:=y; canvas.pen.Mode:=pmCopy; end;

• end; • aktualispoz.caption:='Helyzet: '+inttostr(x)+', '+inttostr(y); • end;

Bittérkép

• Sajnos a programunk még nem tökéletes • Ha átméretezzük az ablakot a rajz egy része eltűnik.

• Ha bittérképet használunk, akkor ez a probléma megoldható.

• Ha kiegészítjük gördítősávval, akkor a kép mérete is tetszőleges lehet.

Bittérkép

• Helyezzünk el egy Scrollbox komponenst a még üres területen, az align tulajdonsága legyen alClient.

• Helyezzünk el benne egy image komponenst. (Name=rajzimage, autosize=true, left=0, top=0)

A bittérkép kezdeti értékei

• Amikor egy image komponenst felrakunk, az még képet nem tartalmaz.

• Ha fix képet tartalmaz, az a Picture tulajdonság beállításával valósítható meg.

• Ha menet közben változik, akkor létre kell hozni egy bitmap objektumot, amit a Picture.Graphic tulajdonsághoz rendelünk hozzá.

• procedure TForm1.FormCreate(Sender: TObject); • var Bitmap:TBitmap;//változó a bitkép tárolására • begin • rajzeszk:=1; • Bitmap:=TBitmap.Create;//létrehozás • Bitmap.Width:=200; • Bitmap.Height:=200;//kezdeti érték • rajzimage.Picture.Graphic:=Bitmap;//hozzárendelés • end;

Megjegyzés

• A program már megfelelő alkatrászekkel rendelkezik, de még mindig az ablakra és nem a bittérképre rajzol.

• A Search menü Replace… parancsával cseréljük ki a Canvas karaktersorozat minden előfordulását rajzimage.canvas-ra • A rajzimage onmousedown, onmousemove, onmouseup eljárásához rendeljük a Form1 megfelelő eljárását, majd a Form1 eljárásai közül ezeket távolítsuk el!

A menürendszer

• Fájl – Új – Megnyitás… – Mentés – Mentés másként… – Nyomtatás – – Kilépés

A menürendszer

• Szerkesztés – Kivágás – Másolás – Beillesztés

• procedure TForm1.Kilps1Click(Sender: TObject); • begin • close; • end;

Probléma

• A menük használatakor fölösleges vonalak jelenhetnek meg.

• A menü felengedése is rajzolási parancsot eredményezhet a programnak, ezt ki kell küszöbölnünk.

• • • • • • • • procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; • Shift: TShiftState; X, Y: Integer); • begin • • • if rajzolhat then begin • case rajzeszk of 1:begin rajzimage.canvas.LineTo(x,y); rajzolhat:=false; end; 2:begin rajzimage.canvas.MoveTo(kezdx,kezdy); rajzimage.canvas.LineTo(x,y); rajzolhat:=false; end;

• • • • 3:begin rajzimage.canvas.MoveTo(kezdx,kezdy); rajzimage.canvas.rectangle(kezdx,kezdy,x,y); rajzolhat:=false; • • end; 4:begin • • rajzimage.canvas.MoveTo(kezdx,kezdy); rajzimage.canvas.ellipse(kezdx,kezdy,x,y); • rajzolhat:=false; • end; • end; • end; • end;

A rajz kinyomtatása

• A nyomtatáshoz használnunk kell a Printers unitot, ezért tüntessük föl az ablak uses sorában!

• Ebben a unitban van a Printer objektum, aminek szintén van Canvas tulajdonsága, ez reprezentálja a kinyomtatandó lapot.

• A nyomtatáshoz a képet erre a canvasra kell másolni.

• procedure TForm1.Nyomtats1Click(Sender: TObject); • begin • printer.BeginDoc;//a nyomtatás kezdete • printer.Canvas.Draw(0,0,rajzimage.Picture.

Graphic);//átmásolás • printer.EndDoc;//a nyomtatás vége • end;

Grafikus állományok kezelése

• A képek kezelésével kapcsolatban a következő műveletekre lesz szükség: – kép betöltése fájlból – az aktuális kép fájlba mentése – az aktuális kép helyettesítése másik képpel

Grafikus állományok kezelése

• Helyezzünk el egy OpenDialog és egy SaveDialog komponenst az ablakra • Állítsuk be a filters tulajdonságukat úgy, hogy a BMP kiterjesztésű állományokat jelenítsék meg • A Form1 public részében vegyünk fel egy AktualisFajl nevű string típusú változót, ami az aktuális kép nevét tartalmazza majd

Képállomány betöltése

• procedure TForm1.Megnyits1Click(Sender: TObject); • begin • if opendialog1.Execute then • • begin aktualisfajl:=opendialog1.FileName; • rajzimage.Picture.LoadFromFile(aktualisfajl); • end; • end;

Kép fájlba mentése

• procedure TForm1.Mentsmsknt1Click(Sender: TObject); • begin • if savedialog1.Execute then • • begin aktualisfajl:=savedialog1.FileName; • rajzimage.Picture.SaveToFile(aktualisfajl); • end; • end;

Kép mentése

• procedure TForm1.M1Click(Sender: TObject); • begin • if aktualisfajl<>'' then • rajzimage.Picture.SaveToFile(aktualisfajl) • else • Mentsmsknt1Click(Sender); • end;

Kép helyettesítése másik képpel

• Ha új képet szeretnénk létrehozni, akkor biztosítanunk kell azt, hogy a kép méreteit beállíthassuk.

• Ehhez hozzunk létre egy új ablakot!

• A form neve legyen kepmeretform • Mentésnél a unitnak adjuk majd a

kepmeret

nevet.

• procedure TForm1.j1Click(Sender: TObject); • var Bitmap:TBitmap; • • • begin kepmeretform.ActiveControl:=kepmeretform.edit1; //inputfókusz beállítása • • • • if kepmeretform.ShowModal<>idCancel then begin bitmap:=TBitmap.Create; bitmap.Width:=kepmeretform.UpDown1.Position; • • • bitmap.Height:=kepmeretform.UpDown2.Position; rajzimage.Picture.Graphic:=bitmap; aktualisfajl:=''; • end; • end;

A vágólap használata

• A Windows vágólapja a Clipboard objektumon keresztül érhető el.

• A főablak uses sorában ehhez fel kell tüntetnünk a ClipBrd unitot.

A kép vágólapra másolása

• procedure TForm1.Msols1Click(Sender: TObject); • • begin clipboard.Assign(rajzimage.picture); • end;

A kép kivágása

• Hasonló a másoláshoz • A végén viszont törölni kell a rajzot a rajzolási területről.

• A rajzterület fehérre festésével.

• procedure TForm1.Kivgs1Click(Sender: TObject); • var rajzterulet:TRect; //a rajz adatainak tárolásához • • begin msols1Click(Sender); //másolás • rajzimage.Canvas.CopyMode:=cmwhiteness; //minden //fehér • rajzterulet:=Rect(0,0,rajzimage.width,rajzimage.height); • • rajzimage.Canvas.CopyRect(rajzterulet,rajzimage.canvas, • • rajzterulet); //saját magára másolás rajzimage.Canvas.CopyMode:=cmsrccopy; //az eredeti //mód • end;

A kép beillesztése

• Meg kell vizsgálni, hogy a vágólapon bittérképes grafika van-e?

• Erre szolgál a Clipboard objektum HasFormat metódusa.

• Ez igaz értékkel tér vissza, ha a formátum a paraméterben megadottal megegyezik.

• procedure TForm1.Beilleszts1Click(Sender: TObject); • var bitmap:tbitmap; • • • begin if clipboard.HasFormat(cf_bitmap) then begin • • • • bitmap:=tbitmap.create; try // ha rendszerhiba történik ez a rész kimarad bitmap.Assign(clipboard); rajzimage.Canvas.Draw(0,0,bitmap); • • • finally // ez mindenképp lefut bitmap.Free; // memória felszabadítás end; • end; • end;

A program elkészült!

VÉGE Készítette: Pető László Természetesen további finomítással, extrákkal bárki szabadon kiegészítheti, vagy készíthet egy jobbat.