Load several images from the same file faster

BlitzMax Forums/BlitzMax Programming/Load several images from the same file faster

Czar Flavius(Posted 2010) [#1]
I have image files which contain a lot of frames, and I'm using LoadAnimImage on them several times each and it's becoming slow. Are there any tricks I can use to speed things up? Can I copy the image to memory and load it from there?


GfK(Posted 2010) [#2]
Should work. Or you could cache it as a pixmap in the same way:
bank:tBank = LoadBank("myfile.png")
image:tImage = LoadAnimImage(bank,64,64,0,2)



Volker(Posted 2010) [#3]
Can't you just use a loader, preload the images and if needed
only pass the reference to the images? You would only
need to load the images once.




Czar Flavius(Posted 2010) [#4]
The images are only loaded once. The problem is that several images are stored within the same, single image file. I don't understand what your code is supposed to do, and won't that use of a list be slow? I would have thought a TMap better.


_Skully(Posted 2010) [#5]
Indeed.. you would be better off returing an integer reference to an array for faster lookups.


Czar Flavius(Posted 2010) [#6]
Maybe I did something wrong but changing the paths to banks saves only 100ms of loading time overall :/

Here's a sample


Global image_banks:TMap = New TMap
Function smart_image_load:TImage(path:String, animation, width = 0, height = 0, first = 0, count = 0, flags = -1)
	Local image:TImage, start_time = MilliSecs()
	Local bank:TBank = TBank(image_banks.ValueForKey(path))
	If Not bank
		Print "Loading from FILE " + path
		bank = LoadBank(path)
		Assert bank
		image_banks.Insert(path, bank)
	Else
		Print "Loading from BANK " + path
	End If
	If animation
		image = LoadAnimImage(bank, width, height, first, count, flags)
	Else
		image = LoadImage(bank, flags)
	End If
	If Not image
		RuntimeError "Cannot find " + path
	End If
	Print "It took " + String(MilliSecs() - start_time) + " milliseconds."
	Return image
End Function


Maybe it's my use of the TMap.. but surely that can't be only 1 millisecond faster than loading from the harddrive??


GfK(Posted 2010) [#7]
If you want to increase loading times purely for images, then you should find that pre-caching as a pixmap rather than a bank will be faster.


ImaginaryHuman(Posted 2010) [#8]
I found that loading RAW image data is faster than loading PNG since there is no decompression needed. You could try that.


Czar Flavius(Posted 2010) [#9]
THANK YOU SO MUCH :D :D




Czar Flavius(Posted 2010) [#10]
In case anybody is reading this hoping to improve their own loading times:
Loading each time from a file instead of bank increases the time from ~90 to ~110 ms, which isn't that much. I suspect it is putting the file into some kind of file cache automatically.

I think the pngs take so long because it is decompressing the png each time. Is there any way to decompress the png once manually to a bmp and storing it in the memory and loading them from there? (<- the last part I know how to do with banks) Then I can have the speed of loading from bmp but without the extra harddisk space required. Use of alpha channels is also highly desirable.


ImaginaryHuman(Posted 2010) [#11]
Once you have loaded the PNG it is stored in a pixmap in its RAW uncompressed format. That's the same thing as storing it `somewhere in memory` uncompressed. So, maybe do LoadPixmap instead of LoadImage.


Czar Flavius(Posted 2010) [#12]


Loading straight png: 474 ms
Loading straight bmp: 91 ms
Loading png as cached pixmap: 66 ms

Global image_pixmaps:TMap = New TMap
Function smart_image_load:TImage(path:String, animation, width = 0, height = 0, first = 0, count = 0, flags = -1)
	Local image:TImage, start_time = MilliSecs()
	Local pixmap:TPixmap = TPixmap(image_pixmaps.ValueForKey(path))
	If Not pixmap
		Print "Loading from FILE " + path
		pixmap = LoadPixmap(path)
		Assert pixmap
		image_pixmaps.Insert(path, pixmap)
	Else
		Print "Loading from RAM " + path
	End If
	If animation
		image = LoadAnimImage(pixmap, width, height, first, count, flags)
	Else
		image = LoadImage(pixmap, flags)
	End If
	If Not image
		RuntimeError "Cannot find " + path
	End If
	Print "It took " + String(MilliSecs() - start_time) + " milliseconds."
	Return image
End Function


Of course, the TMap is cleared after loading is complete so memory is not wasted.


Czar Flavius(Posted 2011) [#13]
Of course, the TMap is cleared after loading is complete so memory is not wasted.

Or it would have been if I hadn't been lazy. It's in fact important to clear this map after loading because about 30mb worth of pixmap data, which had been converted into anim images, was still sitting around in ram. Keeping it there can decrease loading times if the game is restarted, so maybe I will add a cache option for the player.


ima747(Posted 2011) [#14]
Excellent followup, thanks for the details.