Seite 1 von 2
Frage zu den Image ID's
Verfasst: 12.02.2018 17:08
von DarkSoul
Hallo,
ich habe mal eine Frage zu LoadImage():
Doumentation sagt zum Rückgabewert:
Returns nonzero if the image was loaded successfully and zero if the image could not be loaded. If #PB_Any was specified as the #Image parameter then the auto-generated number is returned on success.
Es gibt ja diese zwei Möglichkeiten, ein Bild zu laden:
Code: Alles auswählen
;manuelle Vergabe
bla = 0;
If LoadImage(bla, "xyz.png") = 0 : error....
;automatische Vergabe
bla = LoadImage(#PB_Any, "xyz.png");
If bla = 0 : error....
Wird im zweiten Fall auch die ID 0 vergeben? Wenn ja, wie unterscheide ich den Fall vom Fehlerfall?
Und irgendwann habe ich hier mal als Antwort bekommen, dass folgendes zu Speicherverschwendung führt:
Code: Alles auswählen
LoadImage(0, "xyz.png")
LoadImage(10000, "xyz2.png")
;Jetzt hat das PB-interne ID-Array 10000 Einträge, wovon nur 2 sinnvoll verwendet werden. 1-9999 sind leer.
Jedoch vergibt die #PB_Any-Variante noch viel größere ID's ohne für mich erkennbares System. Ist das dann nicht Speicherverschwendung hoch 3, wenn zigtausende leere Arrayelemente erzeugt werden?
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:17
von NicTheQuick
Ganz einfach:
Mit #PB_Any bekommst du eigentlich ein PB-internes Handle zurück, also eine Speicheradresse. Die kann niemals 0 sein, aber ist meistens auch sehr hoch. Vergleichbar mit den Rückgabewerten von 'AllocateMemory()'.
Bei der Verwendung von festen IDs erstellt Purebasic intern ein Array und nutzt die übergebene ID als Index in diesem Array. Lädst du also ein Image mit der ID 10000, wird ein Array erstellt, das mindestens 10001 Einträge (inklusive Index 0) hat. Und am Index 10000 wird dann der Pointer zur PB-internen Image-Struktur abgelegt. Deswegen kommt auch eine Compilerwarnung, wenn die übergebene Image-ID zu hoch ist. Dann könnte sie sich irgendwann mit den Pointerwerten beißen.
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:18
von RSBasic
DarkSoul hat geschrieben:Wenn ja, wie unterscheide ich den Fall vom Fehlerfall?
Du kannst sowohl den Rückgabewert als auch mit IsImage prüfen, ob das Bild erfolgreich geladen wurde.
Beispiel 1:
Code: Alles auswählen
EnableExplicit
Define Image
Define Result
UsePNGImageDecoder()
DisableDebugger;Nur um Compiler-Warnungen zu ignorieren
Result = LoadImage(1, "D:\Grafiken\Beispielbilder\Beispielbild1.png")
EnableDebugger
If Result
Debug "Erfolgreich"
Else
Debug "Fehler"
EndIf
DisableDebugger;Nur um Compiler-Warnungen zu ignorieren
Image = LoadImage(#PB_Any, "D:\Grafiken\Beispielbilder\Beispielbild1.png")
EnableDebugger
If Image
Debug "Erfolgreich"
Else
Debug "Fehler"
EndIf
Beispiel 2:
Code: Alles auswählen
EnableExplicit
Define Image
UsePNGImageDecoder()
DisableDebugger;Nur um Compiler-Warnungen zu ignorieren
LoadImage(1, "D:\Grafiken\Beispielbilder\Beispielbild1.png")
EnableDebugger
If IsImage(1)
Debug "Erfolgreich"
Else
Debug "Fehler"
EndIf
DisableDebugger;Nur um Compiler-Warnungen zu ignorieren
Image = LoadImage(#PB_Any, "D:\Grafiken\Beispielbilder\Beispielbild1.png")
EnableDebugger
If IsImage(Image)
Debug "Erfolgreich"
Else
Debug "Fehler"
EndIf
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:20
von DarkSoul
Achso
Dann ist alles klar.
Also kann man beide Varianten gleichzeitig nutzen? Ich habe immer nur eine Varante verwendet, um Kollisionen zu vermeiden

Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:21
von NicTheQuick
Ja, gleichzeitiges Nutzen ist kein Problem.

Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:24
von DarkSoul
Danke!
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:34
von #NULL
Variante 4 würde ich vermeiden:
RSBasic hat geschrieben:...Beispiel 2:
Code: Alles auswählen
...
Image = LoadImage(#PB_Any, "D:\Grafiken\Beispielbilder\Beispielbild1.png")
EnableDebugger
If IsImage(Image)
Debug "Erfolgreich"
...
Wenn man Bibliotheken verwendet oder sonst irgendwie static und dynamic IDs gleichzeitig verwendet werden könnten, dann könnte es ein Image 0 durchaus geben und ein fehlschlagendes LoadImage() wird nicht richtig erkannt, bzw sogar das Image 0 aus einem ganz anderen Kontext gekidnappt und verwendet. Also besser nur den Rückgabewert an sich überprüfen, oder für dynamic IDs IsImage() immer mit <>0 checken.
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:43
von Bisonte
Ich persöhnlich nutze (wenn es statisch sein soll) immer Werte erst ab 1...
So kann man einfach gegen Null testen, ohne das man IsGadget oder IsImage usw nutzen muss,
da diese doch langsamer werden können, je mehr Gadgets usw in Benutzung sind.
(Es wird intern ja die komplette Liste durchgeackert bei den IsIrgendwas() Funktionen)
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:48
von NicTheQuick
Bisonte hat geschrieben:(Es wird intern ja die komplette Liste durchgeackert bei den IsIrgendwas() Funktionen)
Weißt du das sicher oder wie kommst du drauf? Warum sollte da eine Liste durchgearbeitet werden?
Ich weiß zwar auch nicht wie sie es machen, wenn man ein dynamisch (#PB_Any) angelegtes Objekt hat, es löscht, und dann IsObject() darauf anwendet, aber Listen durcharbeiten kommt mir komisch vor.
Re: Frage zu den Image ID's
Verfasst: 12.02.2018 17:51
von RSBasic
Mir ist nur bekannt, dass mehr Speicher verbraucht wird, wenn man höhere statische IDs verwendet, da alle freien IDs vorher definiert werden. So war es jedenfalls damals so. Es kann aber auch sein, dass dieses Problem nicht mehr existiert.