Associate an Icon/Image with a String based key

In Swift it is possible to reference a imageset by name, where the name is a STRING value

p=UIImage(named:"myPicture")

I need a way to fake this in Xojo. I have an app right now with a lot of custom objects, and each object can have an icon associated with it.
I want to be able to store the “name of the icon” as a string in a database. While I know I could store a blob, I also need the flexiblty of changing the icon by just changing the name in the database, not to mention multiple records may use the same icon.

And to make matters a bit more complicated :slight_smile:
Each icon is an ImageSet (@1x and @2x)
and there are TWO imagesets per icon (lite_xxx and dark_xxx) so being able to do something like

mode="dark"
iconname="myicon"
p=getIcon(mode+iconname)

would be perfect.

and I THOUGHT that a built app stored ImageSets in a special manner, but it turns out they don’t, the individual images are in the Resources folder

an image basically gives you a global method named the name of the imageset that when you use it loads the images, if they are not already loaded, and you get a picture that is composed of multiple images

what you’re thinking isnt hard to write though - you just cant add it to the Picture global module and call it like
Picture.ImageByName … etc
something like this (this IS forum code so take with a grain of salt)

Public Function ImageByName(baseName as string) as Picture
  Dim pieces() As picture 
  Dim tmpPic As picture
  Dim imageSource As Folderitem
  Dim height As Integer
  Dim width As Integer
    
 imageSource = App.Resources.Child(baseName+".png")
 tmpPic = picture.Open(imageSource)
 height = tmpPic.Height
 width = tmpPic.Width
 picPieces.append tmpPic
    
 imageSource = App.Resources.Child(baseName+"@2x.png")
 If imageSource <> Nil Then
      tmpPic = picture.Open(imageSource)
      picPieces.append tmpPic
    End If
    
  imageSource = App.Resources.Child(baseName+"@3x.png")
    If imageSource <> Nil Then
      tmpPic = picture.Open(imageSource)
      picPieces.append tmpPic
    End If
    
    Try
      Dim imageSetPicture As picture = New Picture(width, height, picPieces)
      
      Return imageSetPicture
    Catch ias As Xojo.Core.InvalidArgumentException
      Return Nil
    End Try    

Thanks… and I guess to speed that up a bit … I could create a dictionary of pictures
and when this is called append it if its not there, or use it if it were?

question… what happens if you have a @1x and @3x but no @2x, or for that matter just @3x
basically if the lower scales are missing

Had to make some modifications to the code you provided :slight_smile:
but I think this works

there isn’t APP.RESOURCES (at least not in 2019r1.1)
and the ImageSource isn’t NIL it may be EXISTS=false
unless of course you give a corrupt filename

I haven’t checked… but would Width/Height have to be divided by picSCALE?
assuming there was no @1x image to base it on?

Public Function ImageByName(baseName As String) as picture
  Dim picScale    As Integer
  Dim picPieces() As picture 
  Dim tmpPic      As picture
  Dim imageSource As Folderitem
  Dim height      As Integer=-1
  Dim width       As Integer=-1
  Dim resources   As FolderItem = SpecialFolder.Resources
  //
  // Based on code provided by Norman Palardy
  //
  For picScale=1 To 3 // @1x @2x @3x
    imageSource = Resources.Child(baseName+"@"+Str(picScale)+"x.png")
    If picScale=1 And Not imageSource.exists Then
      imageSource = Resources.Child(baseName+".png")
    End If
    If imageSource.exists Then 
      tmpPic   = picture.Open(imageSource)
      picPieces.append tmpPic
      If height<0 Then 
        height = tmpPic.Height
        width  = tmpPic.Width
      End If
    End If
  Next picScale
  
  Try
    Dim imageSetPicture As picture = New Picture(width, height, picPieces)
    Return imageSetPicture
  Catch ias As Xojo.Core.InvalidArgumentException
    Return Nil
  End Try   
End Function

Norm… I kinda of figured it was “do it something like this”… but posted above works for what I need

THANKS again :slight_smile: