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(Sender: 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• 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;
3
• vegx:=x;
• vegy:=y;
• canvas.pen.Mode:=pmCopy;
• end;
4• 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;
5
• vegx:=x;
• vegy:=y;
• canvas.pen.Mode:=pmCopy;
• end;
6• 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;
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.
Top Related