#Image from ImageID

Just starting out? Need help? Post your questions and find answers here.
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
User avatar
mk-soft
Always Here
Always Here
Posts: 6207
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: #Image from ImageID

Post 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
 
; ---------------------------------------------------------------------------------------
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Julian
Enthusiast
Enthusiast
Posts: 276
Joined: Tue May 24, 2011 1:36 pm

Re: #Image from ImageID

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