Best way to load or import alot of images/anims?

BlitzMax Forums/BlitzMax Beginners Area/Best way to load or import alot of images/anims?

bizzlebazreese(Posted 2016) [#1]
ive got a ton of image files to import and load. what is the best way to do this?

1. Load them all manually?

2. Use a for loop to import them by naming scheme, knowing the handle of each anim file specifically and copy and paste alot?

i.e.
CurrentAnimString = "anim_name"
For int i To MaxAnimCountThisKind

Imageload CurrentAnimString + "_" + i

or even
CurrentBaseAnimString = "Base_anim_name"
CurrentSubAnimString = "Sub_anim_name"
For int i To MaxAnimCountThisKind

Imageload CurrentBaseAnimString + "_" + CurrentSubAnimString + i

thats a way, but then I have to make a giant for loop.

should I instead save my anim files to a text file and interate throught that instead?

havent gotten into that stuff yet, but I wonder how all of you solve this problem? most games ive seen load anims files from a text document.


Chapman7(Posted 2016) [#2]
One thing you have to keep in mind is how you will reference the image. You could have BlitzMax read through an asset directory and compile all of the .png's to a TList or string array but then how are you going to load/reference them?

Golumn1:TImage = LoadImage(????)

Typically you are going to have a specific image/animated strips for them so you might have to just do it manually.

Alternatively you could do a txt file...

Golumn1;"Assets/Images/Golumn1.png"
Golumn2;"Assets/Images/Golumn2.png"
Bat;"Assets/Strips/Bat.png"

And then do something like

Type Enemy
EnemyType:String
Field Image:TImage
EndType

and then loop through the txt file, creating a new enemy for each line of assets you have, making enemytype Golumn1, Golumn2, etc and loading the image for it.

The only issue with that is to reference that specific enemy, you will have to probably loop through all of the enemies until you reach EnenmyType = "Golumn1" and that could eat a lot of processing time.

Hopefully someone else comes up with something.


Derron(Posted 2016) [#3]
Use a TMap to store your assets - access time should be "a bit" faster than with a TList.
It also avoid multiple entries with the same key


untested (live-written):
global assets:TMap = CreateMap()

local img:TImage
local names:string[] = ["bat", "man"]
local uris:string[] = ["Assets/Images/Golumn1.png", "Assets/Images/Golumn2.png"]
for local i:int = 0 until uris.length
  if names.length <= i then continue
  if uris.length <= i then continue

  img = LoadImage(uris[i])
  if img then Insert(names[i].ToLower, img)
Next

Function GetImageFromRegistry:Timage(key:string)
  key = key.ToLower()
  return TImage(assets.ValueForKey(key)
End Function


You could even extend the "getter" to return a default image if the requested one was not found.



bye
Ron


Midimaster(Posted 2016) [#4]
Do you know, that you can load AnimImages?

Before starting you would connect all single animation frames in one common image (with a graphics editor software like GIMP). At the end you have instead of 20 images with 57x150pix, one single 1140x150pix image.
Now you can use the function LoadAnimImage() in BlitzMax.

SuperStrict
Graphics 400,300
Global Frame%, Time%
Global SandInner:TImage=LoadAnimImage( "SandInner.png",57,150,0,20)
Global SandOuter:TImage=LoadImage( "SandOuter.png")
Global Timer:TTimer=CreateTimer(5)
Repeat
	Cls
	DrawImage SandOuter, 82,60
	DrawImage SandInner, 100,100,Frame
	
	Time=(Time+1) Mod 40
	Frame=Time-10
	If Frame<0 Then Frame=0
	If Frame>19 Then Frame=19

	Flip 
	WaitTimer Timer
Until KeyHit(KEY_ESCAPE)

Control the animation seqence with the parameter FRAME. You are free to run forward/backward, or part sequences, f.e. 5-13. Or stay on one frame for a couple of time, like in my sample code.


Here are the images for the sample code:

SandInner.png:


SandOuter.png:



Derron(Posted 2016) [#5]
Loadanimimage creates individual pixmaps (read "textures") for each anim frame.

While LoadAnim() uses pixmap.window() (virtual copy) it then does a window.copy() ...

Using texture atlases is then the most performant solution.



Bye
Ron


bizzlebazreese(Posted 2016) [#6]
Thanks everyone, the problem however is this

"Assets/Images/Golumn1.png"

or

"SandInner.png"

I guess you gota re-type the file names no matter what. One way or another.


Derron(Posted 2016) [#7]
No..



Either define alle assets in a configuration file... or you traverse through all files in a directory and load them then.

- load filenames of a directory
- loop over them and store the path/uri/filename as key and the loaded image as value within the TMap


Bye
Ron


Midimaster(Posted 2016) [#8]
1. what you plan to do depends on your skills. For me, it looks like you are very new to blitzmax? My opinion is, not to search for the most performant solution, but for a solution you will understand. Are you firm with MAPS? TEXTURE ATLASES?

I suggested to connect all animation frames ( that belong to the same animation) to a single PNG-file and load only one file per animation. This reduces the number of files maybe to 10%... The names are not longer "Enemy1.png", Enemy2.png", ... but "EnemyAnim.png". But this means touching all (!) images and re-name them.
At the end this simplifies your code, when trying to animate all those images.

2. If you have a not so big (<100) number of animations (and each can have a lot of frames), you can do it in a lot of FOR/NEXT loops. You can develop the code, when your skills grow:
All these solutions will work!

STEP 1: LOW SKILLS
"a lot of independent FOR/NEXT loops"
Global Enemy:TImage[10]
For local i%=0 to 9
      Enemy[i]=LoadImage("Enemy" + i+ ".png")
Next

Global Horses:TImage[6]
For local i%=0 to 5
     Horse[i]=LoadImage("Horse" + i+ ".png")
Next
....

It looks like a big amount of code, but for your computer it's nothing

STEP2:
"only one code line per animation"
Global Enemy:TImage[10]=LoadAnimation(10,"Enemy")
Global Horses:TImage[6]=LoadAnimation(6,"Horse")
....

Function LoadAnimation:TImage[](Num%,Name$)
	Local Image:TImage[Num]
	For Local i%=1 To Num
		Image[i-1]=LoadImage(Name + num + ".png")
	Next
	Return Image
End Function 

Here you have one function, which can load all animations, but each animation is still an independent variable. Any text-file-based solution would not be shorter than this! I would go this way with upto 300 animations with upto 3000 image files! No problem

3. Some questions:

In your first post you wrote about your own function "ImageLoad()". Can you post this function here?

How many animations is "a ton of"? How many images do you need to handle?

How do you want to keep track of the animations. Individuell variable names? How will you handle each animation speed?