Page 1 of 2
Re: #Image from ImageID
Posted: Thu Apr 30, 2015 1:40 pm
by Josh
Code: Select all
EnableExplicit
Define nImage
Define hImage
Import ""
PB_Image_Objects
PB_Object_EnumerateStart (*object)
PB_Object_EnumerateNext (*object, *Id)
PB_Object_EnumerateAbort (*object)
EndImport
Procedure.i GetImageFromHandle (hImage)
Define nImage.i
PB_Object_EnumerateStart (PB_Image_Objects)
While PB_Object_EnumerateNext (PB_Image_Objects, @nImage)
If hImage = ImageID (nImage)
PB_Object_EnumerateAbort (PB_Image_Objects)
ProcedureReturn nImage
EndIf
Wend
EndProcedure
nImage = CreateImage(#PB_Any, 20, 20)
hImage = ImageID (nImage)
Debug nImage
Debug hImage
Debug GetImageFromHandle (hImage)
Re: #Image from ImageID
Posted: Thu Apr 30, 2015 2:29 pm
by TI-994A
Hi Josh. Great solution. The
PB_Object_EnumerateStart (PB_Image_Objects) library function/constant does a great job at enumerating only the image objects, solving the
#PB_Any high object number issue.
I've adapted my code to implement these functions, but it still stores the results in a map. That way there will be no need to iterate through all the image objects every time an image number is required; could be pretty slow for large image-intensive projects.
Code: Select all
Import ""
PB_Image_Objects
PB_Object_EnumerateStart (*object)
PB_Object_EnumerateNext (*object, *Id)
EndImport
Procedure initImages()
Global NewMap images.i()
PB_Object_EnumerateStart (PB_Image_Objects)
While PB_Object_EnumerateNext (PB_Image_Objects, @i)
images(Str(ImageID(i))) = i
Wend
EndProcedure
Procedure.i GetImageNumber(imgID.i)
result = -1
If FindMapElement(images(), Str(imgID))
result = images(Str(imgID))
EndIf
ProcedureReturn result
EndProcedure
initImages()
Debug GetImageNumber(validImageID)
It now works with images initialised with
#PB_Any as well.

Re: #Image from ImageID
Posted: Thu Apr 30, 2015 3:22 pm
by Josh
TI-994A wrote:could be pretty slow for large image-intensive projects
9986 Images created and then startet
GetImageFromHandle. Time to find the last image < 1ms. Don't think, you have such a lot images in your project
(I don't know why, but with more then 9986 images I get a problem with MessageRequester)
Re: #Image from ImageID
Posted: Thu Apr 30, 2015 3:39 pm
by TI-994A
Josh wrote:9986 Images created and then startet GetImageFromHandle. Time to find the last image < 1ms.
That's pretty fast. And it would save the additional steps and overheads of using a map.
Josh wrote:(I don't know why, but with more then 9986 images I get a problem with MessageRequester)
Do you mean when iterating with the
PB_Object_EnumerateStart (PB_Image_Objects) function, or when creating more than 9986 images in general?
Re: #Image from ImageID
Posted: Thu Apr 30, 2015 4:02 pm
by Josh
TI-994A wrote:Do you mean when iterating with the PB_Object_EnumerateStart (PB_Image_Objects) function, or when creating more than 9986 images in general?
Seems to be a general problem:
Code: Select all
For i = 1 To 9987
CreateImage(#PB_Any, 20, 20)
Next
MessageRequester ("", "xxx")
With 9986 images the code is running. But this problem is off-topic here and the maximum of 9986 images is not really a problem

Re: #Image from ImageID
Posted: Thu Apr 30, 2015 8:45 pm
by Julian
Thanks Josh and TI, that looks perfect what what I need to do.
The PB_Object_... stuff blows my mind, not they way it works, but that it's seemingly not well documented and seemingly almost impossible to find out about.
I Google'd it and found a German post about it dating back to 2006 but there's no reference to where it comes from, how to use it, who implemented it or where to find out more about it or if there's any other gems like this lying around.
If you two cant shed any more light on it, is there anyone else that can?
Re: #Image from ImageID
Posted: Thu Apr 30, 2015 11:15 pm
by Josh
It's not 'not well documented', it's completely undocumented. You have to take it like it is and its not guaranteed, that it will work in future versions.
Re: #Image from ImageID
Posted: Fri May 01, 2015 6:13 am
by Danilo
Josh wrote:It's not 'not well documented', it's completely undocumented.
The function names and declarations can be found in the PB-SDK "Object.h" header, and some of the
examples in the SDK show how to use those functions. The procedure was originally named ImageFromImageID(ImageID).
Code: Select all
;
; ImageFromImageID.pb
;
; Original by Danilo: http://www.purebasic.fr/english/viewtopic.php?p=386592#p386592
; simplified version by Josh: http://www.purebasic.fr/german/viewtopic.php?f=6&t=26047&hilit=ImageFromImageID&start=4
;
Re: #Image from ImageID
Posted: Fri May 01, 2015 8:05 am
by Josh
Thxs for the info Danilo and sorry, didn't know anymore, where the source came from
Re: #Image from ImageID
Posted: Fri May 01, 2015 11:15 am
by Trond
Override LoadImage() using a macro:
Code: Select all
Global NewMap Images.i()
Procedure LoadImage2(ImageNo, FileName.s)
Protected Result
Result = LoadImage(ImageNo, FileName)
If ImageNo = #PB_Any
If Result
Images(Str(ImageID(Result))) = Result
EndIf
Else
If Result
Images(Str(Result)) = ImageNo
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Macro LoadImage(ImageNo, FileName)
LoadImage2(ImageNo, FileName)
EndMacro
UseJPEGImageDecoder()
UsePNGImageDecoder()
; Load images here
Debug " #, Id"
ForEach Images()
Debug Str(Images()) + ", " + MapKey(Images())
Next
Re: #Image from ImageID
Posted: Fri May 01, 2015 12:47 pm
by mk-soft
also available in "Window Manager" include
http://www.purebasic.fr/english/viewtop ... 12&t=59124
Code: Select all
;- *** Image Objects ***
Structure ImageData
handle.i
id.i
filename.s
EndStructure
Global NewMap ListImages.ImageData()
; ---------------------------------------------------------------------------------------
Procedure MyLoadImage(Image, Filename.s)
Protected result, handle, id, key.s
result = LoadImage(Image, Filename)
If result = 0
ProcedureReturn 0
EndIf
If Image = #PB_Any
handle = ImageID(result)
id = result
Else
handle = result
id = Image
EndIf
key = Str(handle)
AddMapElement(ListImages(), key)
With ListImages()
\handle = handle
\id = id
\filename = Filename
EndWith
ProcedureReturn result
EndProcedure
Macro LoadImage(Image, Filename)
MyLoadImage(Image, Filename)
EndMacro
; ---------------------------------------------------------------------------------------
Procedure MyCatchImage(Image, *Memory, Size = 0)
Protected result, handle, id, key.s
result = CatchImage(Image, *Memory, Size)
If result = 0
ProcedureReturn 0
EndIf
If Image = #PB_Any
handle = ImageID(result)
id = result
Else
handle = result
id = Image
EndIf
key = Str(handle)
AddMapElement(ListImages(), key)
With ListImages()
\handle = handle
\id = id
\filename = ":memory:"
EndWith
ProcedureReturn result
EndProcedure
Macro CatchImage(Image, Memory, Size = 0)
MyCatchImage(Image, Memory, Size)
EndMacro
; ---------------------------------------------------------------------------------------
Procedure MyFreeImage(Image)
Protected key.s
If IsImage(Image)
key = Str(ImageID(Image))
DeleteMapElement(ListImages(), key)
FreeImage(Image)
EndIf
EndProcedure
Macro FreeImage(Image)
MyFreeImage(Image)
EndMacro
; ---------------------------------------------------------------------------------------
Procedure GetImageID(Handle)
Protected result, key.s
result = -1
key = Str(Handle)
If FindMapElement(ListImages(), key)
result = ListImages()\id
EndIf
ProcedureReturn result
EndProcedure
; ---------------------------------------------------------------------------------------
Re: #Image from ImageID
Posted: Fri May 01, 2015 3:35 pm
by Julian
Thanks Danilo, I'll look into that. Thanks Trond and Mk, very cool idea there with the macro!
Plenty for me to get stuck in to here.
Thanks all