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.