#Image from ImageID

Just starting out? Need help? Post your questions and find answers here.
Julian
Enthusiast
Enthusiast
Posts: 276
Joined: Tue May 24, 2011 1:36 pm

#Image from ImageID

Post by Julian »

Hi,

I found this post from 2008:
freak wrote:You cannot get the PB number from an ImageID. This value is stored nowhere on the image object.
Rather than getting the ImageID from a PB Number which Freak says is impossible (understandably), is there a way to access the internal list of "PB numbers" so they can be iterated through to check against an ImageID?

This would be something similar to the access that the PB Library Viewer has, is there a cross platform method of obtaining this data?

Image

Thanks in advance,

Julian
acreis
Enthusiast
Enthusiast
Posts: 204
Joined: Fri Jun 01, 2012 12:20 am

Re: #Image from ImageID

Post by acreis »

I think you could save every Image PB Number created in a list, then iterate through said list.

Best Regards
Julian
Enthusiast
Enthusiast
Posts: 276
Joined: Tue May 24, 2011 1:36 pm

Re: #Image from ImageID

Post by Julian »

Yeah, the problem with that is a lot of people use the form designer, which doesn't automatically insert a nice structure for tracking added images/gadgets etc.

That ultimately means if I want to make a module to alter those and make it a drop in solution, people need to register the images with my module first.

I'll keep hoping and looking.
Julian
Enthusiast
Enthusiast
Posts: 276
Joined: Tue May 24, 2011 1:36 pm

Re: #Image from ImageID

Post by Julian »

Just found a feature request post from 2014 for the same thing...

:( <- me
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: #Image from ImageID

Post by TI-994A »

Julian wrote:...a lot of people use the form designer, which doesn't automatically insert a nice structure for tracking added images/gadgets etc.

That ultimately means if I want to make a module to alter those and make it a drop in solution, people need to register the images with my module first.
Hi Julian. Until the team implements the long-lamented GetImageNumber(fromImageID) function, here's a simple drop-in solution that might work for you.

It's comprised of two short procedures, one to initialise all the images in a project, and another to return the image number from the given image ID:

Code: Select all

;does not work well when images are initialised with #PB_Any as
;PureBasic's #PB_Any initialises objects with very high numbers

Procedure initImages()
  Global NewMap images.i()
  For i = 0 To 1000   ;adjust accordingly
    If IsImage(i)
      images(Str(ImageID(i))) = i
    EndIf
  Next i
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)
The only limitation of this solution is that it does not work well with images initialised with #PB_Any, as the auto-generated numbers are very high and would require bigger loops to find all the images.

Nevertheless, hope you'd find it useful. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: #Image from ImageID

Post 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)
sorry for my bad english
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: #Image from ImageID

Post 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. :)
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: #Image from ImageID

Post 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)
sorry for my bad english
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: #Image from ImageID

Post 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?
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: #Image from ImageID

Post 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 :D
sorry for my bad english
Julian
Enthusiast
Enthusiast
Posts: 276
Joined: Tue May 24, 2011 1:36 pm

Re: #Image from ImageID

Post 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?
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: #Image from ImageID

Post 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.
sorry for my bad english
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: #Image from ImageID

Post 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
;
User avatar
Josh
Addict
Addict
Posts: 1183
Joined: Sat Feb 13, 2010 3:45 pm

Re: #Image from ImageID

Post by Josh »

Thxs for the info Danilo and sorry, didn't know anymore, where the source came from
sorry for my bad english
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: #Image from ImageID

Post 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
Post Reply