Alternatives to stex

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By cgeadas

I would like to know if there is any way to store image files without using stex files.
I’m developing a game with lots (>100) of very big jpeg files (1080 × 2160). Using a tool (http://imageoptim.com) to optimize the files, each jpg is around 450KB. When importing the files to Godot, they get “imported” to streamtextures, and the size goes up to around 4MB each!
Since the game is for Android, I’m limited do 100MB apk. Right now, with just the ARM libs and sound, my apk is around 60MB so, there will be no space for all (not even half!) the images.
I’ve tried creating a pck file to hold the photos “un-imported” and load them as required (speed is not an issue, since it’s a puzzle game). Yet this does not work when exported, not only because the exported executable (tried on mac) doesn’t open the files (there is a warning about it during the export, recommending to just import the images), but because there would be two files to download from Google Play Store, which arises different problems.
So, I am stuck.
I can use the lossy compression during the importing. But then, I already lose quality when making the jpg files, losing quality over that is bad… I can try importing the files unoptimised and hope that Godot does a good job compressing them (which I don’t believe because it’s not even it’s job to do it). But the ideal would be a way to store them within the project and not “importing” them to stex files.

Does anyone found a way to avoid stex files and keep (and use) the jpg files as they are? or any other method that works?.. Thank you.

:bust_in_silhouette: Reply From: cgeadas

Yes, there is :slight_smile:
After further testing, I’ve managed to do it.
First, I’ve tried changing the file extension (from jpg to my_ext) and them load it to memory and pass it as an image. The simplified code to do it is:

var my_file = File.new()
my_file.open("res://image_file.my_ext", File.READ)
var file_size = my_file.get_len()
var mem_temp = my_file.get_buffer(file_size)
	
var img = Image.new()
img.load_jpg_from_buffer(mem_temp)

var texture = ImageTexture.new()
texture.create_from_image(img, 0)
$TextureRect.texture = texture

This way, Godot does not recognise the file as an image and does not import it. However, it also doesn’t export it automatically, when exporting, in Resources, I had to specify that all *.my_ext files should be included. This made see an error I’ve made earlier when trying to use pck files: I had not included them in the export, that’s why it didn’t work.

So this can be made easier by making a zip file with all the photos, and mounting that zip during runtime. Like this:

var err1 = ProjectSettings.load_resource_pack("res://photos.zip")

And then:

var image = Image.new()
# my_picture.jpg is inside the zip file, paths must match
var err = image.load("res://my_picture.jpg")
var texture = ImageTexture.new()
texture.create_from_image(image, 0)

$TextureRect.texture = texture

In this case, when exporting, in Resources, *.zip files must be specified for Godot to include the file with the photos.

Having all this going around with the poolbytearrays of images and the textures and passing the textures to the control is not elegant at all. I guess it consumes much more resources than needed. But the load() texture method of controls and sprites only work with stex images (imported images). So this is the only way I’ve found to bypass the stex files, saving huge amounts of precious storage (if the target platforms were the desktops, it wouldn’t be a problem, but with the 100MB limitation on Android, or the expansion files - while dynamic asset delivery is not a really for Godot), so it seems to me like a satisfying solution.