- Képeken az egyik kameráját elvesztő Sony Xperia 10 VI
- Samsung Galaxy S23 Ultra - non plus ultra
- Samsung Galaxy S24 - nos, Exynos
- Xiaomi 13T és 13T Pro - nincs tétlenkedés
- Mindent megtudtunk az új Nokia 3210-ről
- Megérkezett a Google Pixel 7 és 7 Pro
- Fotók, videók mobillal
- Vodafone-ra áttért Digi Mobilosok
- Apple iPhone 15 Pro Max - Attack on Titan
- Motorola Edge 40 - jó bőr
Hirdetés
-
A franciáknak elege van abból, hogy minden gyerek mobilozik
it Vissza akarják szorítani a gyerekek és tinédzserek közösségi média- és okostelefon-használatát.
-
A virágcsokor mellé hardvert is ajándékozhatunk anyák napján
ph A héten desktop PC-k, monitorok, gamer kiegészítők és házak vannak a kirakatban.
-
iPaden is vége az App Store monopóliumának
ma Ősztől lehet alternatív alkalmazásboltból telepíteni az EU tagállamaiban.
Új hozzászólás Aktív témák
-
Tomi_78
tag
válasz Tomi_78 #2100 üzenetére
Na, ez is sikerült: fehér színűvé tettem a .BMP képcsíkban a hátteret és transparent utasítás helyett a gpkatallkep[i].mask(clWhite);-ot alkalmaztam.
Csak még az a baj, hogy - ahogy eddig is - az alképek bal oldalán egy fekete csík látható. Ezt hogy lehet eltüntetni? Lehet, hogy rossz értéket adtam meg a kép téglalapjának (Rect)? Próbáltam 0 helyett 1-et, 2-t, de ezekkel sem jó, pedig azt hittem, beljebb kéne kezdeni a ciklust ezen értékekkel. -
Tomi_78
tag
És az assembler hibákat hol lehet megnézni, hogy az a kódomban hol van, amikor SIGSEGV osztályú kivétel hibaüzenetet kapok?
Ilyenkor csak megjelenik az Assembly-kódsor és nem tudok mit csinálni, csak hogy bezárom azt az ablakot. Az a baj, hogy gőzöm sincs, hogyan kell debuggolni... -
Tomi_78
tag
válasz Tomi_78 #2104 üzenetére
Megvan, miért jelenik meg a hiba, de sejtelmem sincs, hogy miért és hogyan oldható meg.
Így törlöm a TEgysegek objektum egy példányát, ha már nem kell, mert a letezik változója hamisra állítódott:if egysegdb>0 then
begin
for edb:=0 to egysegdb-1 do
begin
if egysegek[edb].letezik=false then FreeAndNil(egysegek[edb])
else
Ezt az ellenőrzést a pályafrissítő időzítő futtatja le 25 időegységenként. De amikor bekövetkezik ez a FreeAndNil(), akkor dob ki hibával a program.
Akkor nem is ezzel kellene példányt törölni? Próbáltam a Free-t meg a FreeInstance-t is, de mind hibát jelzett, mikor lefutottak. -
vz12
tag
válasz Tomi_78 #2105 üzenetére
0. Meg kellene nézni (debug), hogy az "
egysegek[edb]
" véletlenül se legyen NULL. (valószínűleg nem az, de legyél teljesen biztos benne)1. Lehetne ezt a mintát követni, a "véletlen" problémák kivédése okán:
if Assigned(x) then FreeAndNil(x);2. A fent említett mutatóra CAST-olnám a saját típusát, szintén csak a biztonság kedvéért, ez amúgy SOHASEM árt.
/ FreeAndNil(TDeklaráltTipus(egysegek[edb]
)); /3. Megpróbálnám ezt is, ez az "eredeti" pascal megoldás, 2 lépésből áll:
dispose(TDeklaráltTipus(egysegek[edb]
);egysegek[edb]
:=nil;
/ Tudom, hogy a "FreeAndNil" is elvileg pontosan ezt csinálja, csak 1 lépésben, de azért gyakorlati tapasztalat szerzése céljából én kipróbálnám. /
---------------------
Én a típuskényszerítéstől várnám a megoldást, mert a "sima Free" túl általánosnak tűnik, "mindenre" IS működnie kell, ezért valószínűleg sima "Pointer" vagy "TObject" hivatkozásokkal dolgozik.[ Szerkesztve ]
-
Tomi_78
tag
Köszi a választ, de egyelőre még nem jó.
Az imént próbáltam ezzel is a FreeAndNil() helyett: delete(egysegek,edb,1); de hiába - bár most más Assembly utasítást dobott fel.
A másik, bár kevésbé lényeges probléma, hogy ha ez a kóddarab van a FormPaint-ban:if egysegdb>0 then
akkor miért mindig kék színű lesz a radarobj téglalap? Még a nem játékos irányította egységeknél is? Mert azoknál sárga kellene, hogy legyen.
begin
for edb:=0 to egysegdb-1 do
begin
if egysegek[edb].letezik=true then
begin
if egysegek[edb].tulaj='jatekos' then
canvas.brush.Color:=clBlue
else
canvas.brush.Color:=clYellow;
radarobj.left:=2+Round(egysegek[edb].xhely / (palyakep.canvas.width / opanelkep.width+2));
radarobj.top:=radyeltol+Round(egysegek[edb].yhely / (palyakep.canvas.height / opanelkep.width+6));
radarobj.right:=radarobj.left+2;
radarobj.bottom:=radarobj.top+2;
canvas.rectangle(radarobj);
end;
end;
end; -
Tomi_78
tag
válasz Tomi_78 #2107 üzenetére
Na, most így sikerült kijavítanom:
if egysegek[edb].letezik=false then
begin
delete(egysegek,edb,1);
dec(egysegdb,1);
end
Bár az a gyanúm, hogy ez be fog kavarni kicsit, mert ha átrendeződik az egységek sorrendje, akkor a játékosé átkerülhet a számítógépéhez és fordítva, stb.
Na mindegy, ez majd kiderül.
De a radarobj miért kék még mindig? -
vz12
tag
válasz Tomi_78 #2107 üzenetére
Ezt leginkább csak debug-olással lehet kideríteni, nálad.
Legyen egy töréspont az "if"-en, és sor léptetésekkel haladva le kell kérdezgetni a kérdéses adatokat. A számítógépnek biztos, hogy igaza van, vagyis valahol valamilyen érték nem fog stimmelni, onnan kell majd tovább nyomozni. -
Tomi_78
tag
Sziasztok!
Azt szeretném megtudni, hogy Lazarus FreePascal-ban ha Assembly hibaüzenetet kapok, mint a mellékelt képen, akkor abból hogyan deríthetem ki, hogy az a forráskódban melyik sort jelenti?
Sajnos a debugoláshoz egyáltalán nem értek, de a programom valami "External SIGSEGV osztályú kivétel" hibaüzenettel, majd az Assembly ablakkal áll le.
-
vz12
tag
válasz Tomi_78 #2110 üzenetére
Hello!
A pontos választ nem tudom, de gyors kereséssel az alábbi lehetséges okokat dobta a Google:
If a program gets a segmentation fault (SIGSEGV), it references a memory address outside of the memory available to it.
The most frequent causes for a segmentation fault are:
An array index is outside the declared range.
The name of an array index is misspelled.
The calling routine has a REAL argument, which the called routine has as INTEGER.
An array index is miscalculated.
The calling routine has fewer arguments than required.
A pointer is used before it is defined.Valószínűleg ezek csak példák, tehát lehetséges más ok is, de kiindulási alapnak talán elegendő.
A debugolást tessék megtanulni, nagyon leegyszerűsíti a hibakeresést, a Delphi-ben a beépített debugger nagyon egyszerűen és kiválóan működik, a Lazarus-ban lévő pedig a képek alapján kb. ugyanaz lehet.
Az első G-s találat a "debug in Lazarus"-ra ez, ránéztem, tök jó:
[link]Egyébként ezt a hibát NEM biztos, hogy
lehetségeskönnyű megtalálni, mert ha pl. iterációban, időzített futásban, stb., tehát ha NEM az első ráfutáskor, hanem később "menet közben valamikor egyszercsak" jelentkezik a probléma, a változók változásai miatt, vagy ha a debugolás miatti megállások megváltoztatják a környezeti (idő) feltételeket, akkor bizony rá kell szánni az időt. És neked még azt is be kell határolni, hogy vajon HOVA kellene töréspontot tenni (ahol - még egyszer mondom - lehet hogy az első N db alkalommal akár minden rendben is van, tehát hiába állítod meg ott a programot, csak utána romlik el ugyanott "valamikor"). Először az F8-akat kellene nyomkodni, és ha megvan, hogy miben száll el, akkor (elölről kezdve) ugyanott F8 HELYETT F7-tel kellene OTT mélyebbre menni, ahol 1-gyel mélyebb szinten először szintén F8, utána F7. Amikor már nem lehet mélyebbre menni (F7), akkor megtaláltad a hibapontot, és kiakadás előtt meg kell vizsgálni a változók, objektumok, tömbök, stb. tartalmait akár ezek "watch"-olásával, akár az egér sima elem fölé húzásával, ahogy a fenti videóban is mutatják, és a kiírt értékek alapján NEKED már látnod kellene a problémát.A fentiek alapján MEGELŐZÉSSEL is lehetne kísérletezni, brutál validációkkal (kissé túl erőltetettnek tűnő IF-ezéssel) a tömb indexek és a mutatók/pointerek felhasználását tekintve. A rossz függvény paraméterezést kevéssé tartom valószínű oknak, azt talán "rendesen" is meg tudja mondani a Lazarus, de ki tudja.
Esetleg (de ez csak ötlet) ha képernyő/pálya frissítésével függ össze a hiba, akkor LEHET, hogy a megadott frissítési idő kevés, ezért "összetorlódnak" a feladatok, amit már nem bír elviselni a rendszer, vagyis próbálkozni lehet a frissítés idejének megnövelésével is VAGY a pályaméret csökkentésével VAGY a frissítéskor lefutó kód gyorsításával, amennyiben az még nem optimális.[ Szerkesztve ]
-
Tomi_78
tag
Hű, köszönöm, Vz12, a gyors és alapos választ!
Még tegnap ezt találtam a SIGSEG-vel kapcsolatban, amikor kerestem:
[link]
Be is kapcsoltam a kipipálható dolgokat a Hibakeresőben, és azután nem jelentkeztek a hibák. Csak hát én kipipálás nélkül is szeretném tudni az okokat és akkor is hibamentesnek szeretném tudni a programomat, nameg érteni azt, hogy mit pipáltam ki.
Ma kivettem a jelölőnégyzetekből a pipákat és erre megint hibát dob fel egy kis idő után.
A videót is köszönöm; még ma megnézem okvetlenül. És az F8-asozást is kipróbálom. -
vz12
tag
válasz Tomi_78 #2114 üzenetére
> "Cannot find bounds of current function"
És van a függvénynek eleje/vége? El sem kellene indulnia a programnak, ha ilyen hiba van benne, ez az üzenet számomra nagyon furcsa, gyakorlatilag értelmezhetetlen.> F9-re is ezt írja ki
Újraindítás után, MIELŐTT F9-et nyomnál, próbáld meg törölni az összes töréspontot:
Nézet/Hibakereső ablakok/Töréspontok (Ctrl+Alt+B)
Nyilván itt ki kellene jelölni az összes töréspontot, majd törlés.
Ha utána sikeresen elindul, akkor - ha még nem ment el a kedved tőle - meg lehet próbálni a futtatást.
A Shift+Ctrl+F9-cel a "Futtatás/Futtatás hibakeresés nélkül" esetén elvileg szintén nem szabadna annak a csúnya "Hibakereső Hiba" ablaknak megjelennie, hiszen nincs hibakeresés. De ez már lehet hogy egy Lazarus hozzáértő segítségét kívánja.
Ha "megjavult", akkor ÉN nagyon óvatosan (messziről haladva, egyesével, vagy csupán csak 1-et) megpróbálnám újra felvenni a törésponto(ka)t.
Akkor tudok ilyen hiba ablakot esetleg elképzelni, ha a töréspont a hiba UTÁN lett téve, és a hiba hatására valamilyen kezelhetelen állapotban beragadt a Lazarus.
Bízom benne, hogy teljes újratelepítés NEM szükséges, mert az durva lenne.
Sosem voltam ilyen helyzetben, tehát ezt nem tudom. -
Tomi_78
tag
Amúgy ennek a lehetőségnek mi értelme van a Projekt beállításai/Hibakeresés-ben:
Hibakeresési információk létrehozása a GDB számára (lassabb / nagyobb exe-méret) ?
Mert én ezt most kikapcsoltam, hogy ne legyen olyan óriási az EXE. De ha visszakapcsolnám és futtatnám az EXE-t, akkor rendesen kiírná a hibát vagy mi? -
Tomi_78
tag
Talán megvan a hiba oka: ha megsemmisül egy játékegység, akkor lép ki a program - legalábbis úgy látom.
A játékobjektumok példányainak van egy letezik boolean típusú tulajdonsága, ami false lesz, ha megsemmisül. Ezt mindig ellenőrzöm, hogy true vagy false, bármikor szóba kerül egy objektum.
Amikor ciklussal végigmegyek a példányokon, ellenőrzöm, hogy létezik-e, ha meg nem, akkor jön a FreeAndNil (vagy a Delete, de azzal sem jó). Ha meg létezik, akkor jöhetnek vele a műveletek.
De ilyen ciklusok nemcsak a pályafrissítés eljárásban, hanem sok másban is vannak velük, pl. a FormPaint-ben. De mindig leellenőrzöm, hogy létezik-e, ha műveletet végzek velük.
Akkor ez most nem jó megoldás a példányok kezelésére, törlésére? Lehet, hogy a dinamikus tömb kezelése nem jó, ami tartalmazza őket? Vagy hogy kell ezt csinálni szabályosan? -
vz12
tag
válasz Tomi_78 #2118 üzenetére
Nos, ha timer-rel frissíted "valamikor" a pályát MIKÖZBEN esetleg a törlések éppen zajlanak, az nem tűnik szerencsésnek. Itt valamilyen minimális szervezésnek illene lennie, pl. egy logikai változónak, hogy éppen "karbantartás" zajlik, ilyenkor a frissítés legyen blokkolva. A karbantartás végeztével a logikai változó megváltozásával ismét mehet a frissítés. Tehát a törlések UTÁN a megváltozott állapotra kell ráengedni a frissítést.
Esetleg - ez még jobb - lehet 2 db logikai változó is, oda-vissza ellenőrzéssel, addig nincs frissítés, amíg karbantartás van, illetve addig nem kezdődik karbantartás, amíg zajlik a frissítés.
Mondom ezt csak ötletként, a pontos kód ismerete nélkül, de amúgy lehet, hogy eddig is ez az egyidejűség okozta a problémádat.
Ezek a változók lennének az ún. "szemafor"-ok, ennek van hagyománya a programozásban, és kb. ilyen esetekben használják őket, az egyidejűség elkerülésére, hogy ne legyen "karambol". -
Tomi_78
tag
Igen, a bekapcsolásával már érthetőbb lett az üzenet: pontosan kiírta, hogy melyik sor a hibás! Igaz, ezzel nem jutottam közelebb a megoldáshoz, mert nem tudom, hogy miért nem jó az.
Lehet, hogy mégis a frissítéssel van a gond, ahogy írod? A példányok törlése valóban így megy 25 fps-es "invalidate"-enként:
procedure TForm1.palyafrissites(Sender: TObject);
begin
ha nem létezik, törlés, különben műveletek vele.
with canvas do invalidate;
end; -
Tomi_78
tag
Az imént átírtam ezeket:
egysegek[edb].letezik=true
erre:
egysegek[edb]<>nil
és így úgy tűnik, megszűntek a hibák. Valamint a törlést:
freeandnil(egysegek[edb]);
dec(egysegdb,1);
setlength(egysegek,egysegdb);
az eddigi egyetlen, letezik=false jelölésű helyről áttettem minden olyan helyre, ahol eddig ezt a letezik változót hamisra állítottam.
De akkor ezek szerint a FreeAndNil() nem azonnal töröl? Csak nil-re állítja az objektumpéldányra a mutatót? -
vz12
tag
válasz Tomi_78 #2122 üzenetére
Nagyon jó változtatásnak tűnik a "letezik" helyett a "nil"-re vizsgálni, jó ötlet volt.
> a FreeAndNil() nem azonnal töröl?
A neve alapján illene azonnal törölnie.
Ezt találtam gyorsan róla a neten: It calls an object's destructor
Vagyis elvileg valóban töröl, megsemmisít, de többet erről csak az tud, aki írta a forráskódját ...Ha tényleg megszűntek a hibák, akkor "megérte" ennyit foglalkozni vele, valószínűleg sokáig megmaradó tapasztalatot szereztél vele, csak így tovább.
-
vz12
tag
válasz Tomi_78 #2124 üzenetére
Nincs mit.
Valóban nem könnyű, és ezt a "civilek" legtöbbször nem látják, sokszor téves elképzeléseik vannak magáról a feladatról is, meg annak adott körülmények közötti megvalósításáról is, pl. időigény, stb. Az még a legszerencsésebb helyzet, ha az ember "nyomás nélkül" saját magának írja a programot, és van rá elég ideje meg elhivatottsága is. -
Tomi_78
tag
Na de ez a hibajelenség miért van:
Van egy kilépésgomb a programomban, melyet így hozok létre és rendelem hozzá a kilépés kezelését végző függvényt:
kilepgomb:=TButton.Create(form1);
kilepgomb.Parent:=form1;
kilepgomb.Top:=2;
kilepgomb.Left:=2;
kilepgomb.Caption:='Esc';
kilepgomb.OnClick:=@kilepgombkatt;
Ugyanakkor az ESC billentyű lenyomásával is szeretném vezérelni a kilépést, ezért ez van a FormKeyDown-ban:if Key=VK_ESCAPE then
kilepgombkatt(form1)
else (...)
A kilepgombkatt()-ban ez történik:procedure TForm1.kilepgombkatt(Sender: TObject);
var valasz,stilus: integer;
begin
stilus:=MB_ICONQUESTION + MB_YESNO;
valasz:=Application.MessageBox('Biztosan ki akarsz lépni?', 'Megerősítés', stilus);
if valasz=IDYES then close;
end;
Ha rákattintok egérrel a gombra és a NO-t választom, és utána egér helyett az ESC gombbal próbálnám ezt megint aktivizálni, akkor nem történik semmi. Magyarán ezután csak az egérkattintással tudok kilépni.
Miért van ez így; mi történik a programban és hogyan javítható? -
vz12
tag
válasz Tomi_78 #2126 üzenetére
kilepgomb:=TButton.Create(form1);
kilepgomb.Parent:=form1;
kilepgomb.Top:=2;
kilepgomb.Left:=2;
kilepgomb.Caption:='Esc';
kilepgomb.OnKeyDown:=@FormKeyDown;
kilepgomb.OnClick:=@kilepgombkatt;Amikor a kilépés gombon állsz, akkor nem aktív a form, vagyis a bill. lenyomás NEM a form keydown-ja, hanem a button keydown-ja.
Pl. a fenti módon át lehet irányítani az eseményeket, így "közös" keydown-ja lesz a gombnak és a formnak.
-
vz12
tag
válasz Tomi_78 #2128 üzenetére
"Focus is the ability to receive user input through the mouse or keyboard. Only the object that has the focus can receive a keyboard event. Also, only one component per form can be active, or have the focus, in a running application at any given time.
Some components, such as TImage, TPaintBox, TPanel and TLabel cannot receive focus. In general, components derived from TGraphicControl are unable to receive focus. Additionally, components that are invisible at run time (TTimer) cannot receive focus."
-----------------
Itt van még valami:
To trap keystrokes at the form level instead of passing them to the form's components, set the form's KeyPreview property to True (using the Object Inspector). The component still sees the event, but the form has an opportunity to handle it first - to allow or disallow some keys to be pressed, for example.Magát a formot közvetlenül NEM bill. inputra tervezték (az a rátehető objektumok egy részének a feladata), de eseménykezelője van, a form csak úgy figyel a háttérben.
Ha a formon beállítod a "KeyPreview=true"-t, akkor ELSŐDLEGESEN (központosítva) a form eseménykezelője dolgozza fel a bill. eseményeket, pl. a keydown-t is, MAJD AZUTÁN annak az objektumnak (pl. gombnak) a pl. keydown-ja is lefut, ahonnan a bill. lenyomás érkezett. A sorrend fontos, a form eseményben trükközni is lehet, mielőtt az objektum feldolgozná a bill. nyomást.
Ha a "KeyPreview=false", akkor a form bill. kezelő eseményei hatástalanok (ez történt nálad is, mert a "false" az alapértelmezett). Ilyenkor az általam írt "központosítás", mint módszer/trükk használható, tehát a formon lévő OBJEKTUM eseménykezelője kapja el a bill. nyomást (mert a formé nem fogja), de a form eseménykezelője hajtra végre. Ez jó akkor, ha pl. nem akarod, hogy minden objektum esetén végrehajtódjon a "központi" kód, csak azoknál amelyeknél beállítod, illetve nem akarsz többszörösen (redundánsan) kódolni.
A gyakorlatban: (a kilepgomb.OnKeyDown ki van kommentelve)
form1.KeyPreview:=true;
kilepgomb:=TButton.Create(form1);
kilepgomb.Parent:=form1;
kilepgomb.Top:=2;
kilepgomb.Left:=2;
kilepgomb.Caption:='Esc';
// kilepgomb.OnKeyDown:=@FormKeyDown;
kilepgomb.OnClick:=@kilepgombkatt; -
vz12
tag
válasz Tomi_78 #2129 üzenetére
Hát, nem tudok mit mondani, vettem a fáradtságot, és LAZARUS-ban kipróbáltam, mielőtt beküldtem ide, és nálam működött.
A form "KeyDown"-ja valóban a "FormKeyDown" eljárásra mutat? Nálad is az a neve? Nem változtattad meg? Mert ha igen, akkor a megváltoztatott eljárás nevet kell odaírni a vastagbetűs sorba, de ez triviális.
Nem tudom, hogy mi a problémája a pupup menüvel, meg hogy milyen töréspontokról van szó, meg hogy milyen köze van a "keydown"-hoz, szerintem semmi.
[ Szerkesztve ]
-
Tomi_78
tag
Az lehet baj, hogy maga a gomb létrehozás is a FormKeyDown() eseményben van? A következőképpen:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
);
begin
if Key=VK_ESCAPE then
kilepgombkatt(form1)
else
begin
case jatallapot of
2: begin
kilepgomb:=TButton.Create(form1);
kilepgomb.Parent:=form1;
kilepgomb.Top:=2;
kilepgomb.Left:=2;
kilepgomb.Caption:='Esc';
kilepgomb.OnKeyDown:=@FormKeyDown;
kilepgomb.OnClick:=@kilepgombkatt;
-
vz12
tag
válasz Tomi_78 #2132 üzenetére
Szerintem az baj, bizony.
Én a FormCreate-be tettem, illetve a programozott létrehozásokat, valamint a kezdeti beállításokat a fő formra vonatkozóan mindig odateszem.
Legfeljebb ELREJTEM addig, amíg nem kell.Ahogy látom, a "jatallapot=2" esetén lehet, hogy elég sokszor létrehozza azt a gombot és esetleg besokall a gép, persze nem ismerem a vezérlésedet, de onnan tedd át máshova gyorsan, ami garantáltan egyszer fut le, pl. a FormCreate-be.
[ Szerkesztve ]
-
Tomi_78
tag
És az miért van, hogy ebben a kis képméretező programomban mindig eredeti, nagy méretben mentődik el a betöltött kép, holott ha más értékeket adok meg neki az Edit1 és Edit2-ben, akkor abban mutatja a Form-on, de elmenteni mindig az eredetiben menti el?
procedure TForm1.Button2Click(Sender: TObject);
var ujkep: TImage;
begin
if ListBox1.ItemIndex<>-1 then
begin
ujkep:=TImage.Create(Self);
ujkep.parent:=Form1;
ujkep.autosize:=false;
ujkep.Proportional:=true;
ujkep.Stretch:=true;
ujkep.picture.bitmap.setsize(strtoint(Edit1.Text),strtoint(Edit2.Text));
ujkep.Picture.LoadFromFile(mappa+ListBox1.Items.Strings[0]);
ujkep.picture.SaveToFile(mappa+'PROBA.png');
//ujkep.free; //Mutatja a Form-on a kisképet, ha kommentelt.
end;
end; -
vz12
tag
válasz Tomi_78 #2134 üzenetére
Nos, nem nagyon értek hozzá, de nem gondolnám, hogy csupán property-k állítgatásával újraÉPÍTI (konvertálja) a kép tartalmát, ezért menthette az eredeti képet. A property-k a vizualitásra hatással lehetnek, de BELÜL a kép szerintem NEM változik.
Ezen link alapján (ott "
procedure TForm1.Button2Click(Sender: TObject);
") írtam egy egyszerű működő példát Delphi-ben, még a képernyőn sem jelenítettem meg semmit (a gombon kívül), csak gombnyomásra legyártja egy kép kicsinyített mását a méretarány megtartásával.
1280x905 helyett 100x71 pixel.
672 Kb helyett 5 Kb.
Ja, a példa JPG-vel dolgozik, tehát JPG-ből JPG-t csinál (a köztes állapot BMP).
Ha fontos a PNG, azt Te nyomozd ki.procedure TForm1.Button1Click(Sender: TObject);
var Source: TJPEGImage; Dest,Temp: TBitmap;
begin
Source:=TJpegImage.Create;
try
Dest:=TBitmap.Create;
try
Temp:=TBitmap.Create;
try
Source.LoadFromFile('VALAMI.JPG');
Source.DIBNeeded;
Dest.Assign(Source);
Temp.width:=100;
Temp.height:=Round(Source.height*(Temp.width/Source.width));
Temp.Canvas.StretchDraw(Rect(0,0,Temp.width,Temp.height), Dest);
Source.Assign(Temp);
Source.SaveToFile('PROBA.JPG');
finally
Temp.Free;
end;
finally
Dest.Free;
end;
finally
Source.Free;
end;
end;
A "Temp.SetSize()" nálam nem működött, azért változtattam meg.
Olyan sok képformátumot NEM kezel a Delphi/Lazarus, tehát egy "általános" képkonvertáló program írására a fenti egyszerű módszerrel nem lehet messzire jutni.
Kép méretezésre jó lehet JPG, BMP esetén.[ Szerkesztve ]
-
Tomi_78
tag
Jó lett, csak átlátszóság nincs, hanem fekete keretben van a képecske. Akkor lehet, hogy azt nem is tudja kezelni? Ez a kódom:
procedure TForm1.Button2Click(Sender: TObject);
var tarolokep,kiskep: TBitmap;
ujkep: TPortableNetworkGraphic;
begin
if ListBox1.ItemIndex<>-1 then
begin
kiskep:=TBitmap.Create;
ujkep:=TPortableNetworkGraphic.Create;
tarolokep:=TBitmap.Create;
ujkep.transparent:=true;
kiskep.transparent:=true;
tarolokep.transparent:=true;
kiskep.Width:=strtoint(Edit1.Text);
kiskep.Height:=strtoint(Edit2.Text);
ujkep.LoadFromFile(mappa+ListBox1.Items.Strings[0]);
tarolokep.assign(ujkep);
kiskep.canvas.StretchDraw(rect(0,0,kiskep.width,kiskep.height),tarolokep);
ujkep.assign(kiskep);
ujkep.savetofile(mappa+'PROBA.png');
kiskep.free;
ujkep.free;
tarolokep.free;
end;
end; -
-
Tomi_78
tag
Végül megtaláltam erre az áttetszőséges gondra a megoldást, ugyanis hirtelen ötlettől vezérelve megnéztem a bitmélységét a forrásképnek és az elmentettnek, és az előbbinek 32, míg az utóbbinak csak 24 bit.
Ennek alapján ki kellett egészítenem a kódot ezzel a sorral:ujkep.pixelformat:=pf32bit;
Az is fontos, hogy ez a kiegészítés a StretchDraw-ot tartalmazó sor elé kerüljön, különben ha utána tesszük, valamiért egy üres képet eredményez elmentve!
Úgy örülök, hogy sikerült megcsinálni, mert sok képszerkesztési munkától fog megkímélni ez a kis program, ha végül készen lesz. -
Tomi_78
tag
Bizony jó érzés, és még jobb végre elkészülni a programmal. Ez egy kis képszerkesztő, amivel egyszerre nagy mennyiségű képet lehet átméretezni és átnevezni. Talán másoknak is jól jöhet, ezért beillesztem ide a letöltési címét: [link]
És még egyszer, ezer köszönet a segítségért, Vz12! Bár a programfejlesztéssel ezzel nem állok le, sőt, vannak egyéb játékok és felhasználói programok még, amik megvalósításra várnak, ezért nem kizárt, hogy jövök még ide. -
Tomi_78
tag
Sziasztok!
Valaki tud nekem segíteni abban a problémámban, hogy hogyan lehet átdefiniálni a programban a gombokat? Tehát most pl. a nyíl gombokkal irányítok, de szeretném, ha a felhasználó ezeket kedve szerint állíthatná be.
Hogy lehet a lenyomott gomb kódját eltárolni és felhasználni? Milyen adattípus kell hozzá?
Most VK_LEFT, VK_RIGHT, VK_UP és VK_DOWN van használatban. -
vz12
tag
válasz Tomi_78 #2142 üzenetére
Hááát, szerintem a help-ben benne kellene lennie a kódoknak, vagy a Google is segít, pl. a "Delphi key codes" keresése után, rengeteg találat van.
Ha a numerikus kódokat saját szemeddel akarod látni, akkor pl. az OnKeyDown bemenő paramétereit írasd ki, ezeket el is tudod tárolni, mondjuk egy INI fájlban, majd később ezeket vissza is tudod olvasni, szövegből numerikus típussá alakítva vizsgálni is tudod. A régebbi Delphi-kben ez WORD típus, az újakban nem tudom. Kis/nagybetűkre figyelj.[ Szerkesztve ]
Új hozzászólás Aktív témák
- Sweet.tv - internetes TV
- Fűnyíró topik
- Súlyos adatvédelmi botrányba kerülhet a ChatGPT az EU-ban
- Képeken az egyik kameráját elvesztő Sony Xperia 10 VI
- Eredeti játékok OFF topik
- Samsung Galaxy S23 Ultra - non plus ultra
- AMD K6-III, és minden ami RETRO - Oldschool tuning
- Debrecen és környéke adok-veszek-beszélgetek
- E-roller topik
- Kormányok / autós szimulátorok topicja
- További aktív témák...
- BESZÁMÍTÁS! Lenovo Thinkcentre M720S i5 16GB 1TB SSD számítógép garanciával hibátlan működéssel
- BESZÁMÍTÁS! HP Omen 15 15 FHD Gamer notebook - i7 10750H 16GB RAM 1TB SSD RTX 2070 8GB WIN
- Lenovo Thinkpad T495 Ryzen 5 PRO 3500U/16GB RAM/256 SSD/14" FULL HD garanciás laptop eladó
- Panasonic Lumix G X VARIO 12-35mm f/2.8 II ASPH. Power O.I.S. (H-HSA12035)
- 2db Iceriver KS0 KASPA bányagép + 180W új tápegység 2 év garanciával.
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: Ozeki Kft.
Város: Debrecen