ImageTexture Cache Not Loaded / Replaced In the Runtime

Godot Version

4.3 Stable

Question

The Image below it’s the thing that i currently working on right now, and i need some help
example_thumbnail_project

So I have a script that can be used for getting an image from camera (Like taking a Screenshot from Camera 3D) and save it into some folder by using “full_path” like below:

func screen_shot(path_name: String) -> void:
	var basePath: String = SettingsManager.get_project_location("Projects/" + path_name + "/Libraries/SceneThumbnails/")
	var ss_name: String = "thumbnail_" + str(scene_count) + ".png"
	var full_path: String = basePath + ss_name
	
	# Remove The Image First (I think the save_png func will auto replace it, but just to make sure it's working)
	DirAccess.remove_absolute(full_path)
	OS.move_to_trash(ProjectSettings.globalize_path(full_path))
	
	await RenderingServer.frame_post_draw
	var img: Image = main_camera_3d.get_viewport().get_texture().get_image()
	var result = img.save_png(full_path)

The function for saving the png is working as intended, but for some reason i need to exit the game first to make the png refreshed

btw, I’m checking the absolute path for the png, (it’s not the code that i make, im simplify the code for a clearer example):

var image_var: String = "E:/.../.../Libraries/SceneThumbnails/thumbnail_1.png"

func get_image() -> void:
	... do something first ...

	load(image_var)

	... do other thing ...

but for some reason in my godot editor, the png file it’s auto reimporting the assets like this below (when i exit the game or just opened the editor) but it still not refreshing the image:
godot_auto_reimport_in_editor

Because of how godot editor reimporting thing like that, now I’m thinking…

  1. How can i restart the game? I’m using something like this code right now, but it doesn’t refresh the png at the runtime
get_tree().change_scene_to_file("res://Scene/Window/MainUILoad.tscn")
  1. Im looking at reddit, and someone say the EditorFileSystem can be used to force refresh the file. but for some reason that guy doesn’t make any example on how to use it. so…
    This is my script attempt right now, but it’s still failed, the variable it’s become null instead.(Please let me know if you know how to use abstraction class or etc):
func refresh(full_path: String) -> void:
	var editor = ClassDB.instantiate("EditorFileSystem")
	editor.update_file(full_path) # to Force to update the file with path
	editor.scan_sources() # to check if the source of any imported resource changed
  1. Any other idea on how can i implement the force refresh thing? or is it not yet implemented in the godot 4?

After this, why not just update the image in game (by changing its texture, etc)?

Thank you for responding, but yeah i’m already try that methode by doing something like this one, but weirdly it still not refreshing the image in the runtime:

var image_var: String = "E:/.../.../Libraries/SceneThumbnails/thumbnail_1.png"

func get_image() -> void:
	... do something first ...

	load(image_var)

	... do other thing ...

Perhaps im missing something?, the func of img.save_png name is the same like this “thumbnail_1.png”, so of course it will going to auto replace the png. (I check the editor is replaced) But in the runtime… it’s not refreshing the new png one until im quiting the runtime (I think godot still using the old image one like a cache perhaps?)

I have something in my mind but it’s still blurry and maybe i’m just oversight it.
It’s something like…

  1. maybe saved the png first with the name of Time.get_time_string_from_system ,
  2. change the path of the image into the name of Time.get_time_string_from_system
  3. when it’s done, delete the thumbnail_1.png
  4. then change the Time.get_time_string_from_system name into thumbnail_1.png
  5. after that change the path from the Time.get_time_string_from_system into thumbnail_1.png

idk if this will work, i’m still doing something else so yeah, if there isn’t any workaround that as easy as force refreshing the assets in the runtime… perhaps i will try that one then hahaha

What does this do:

load(image_var)

When I mention updating the image, I mean godot has the image already (img.save(...)), just change the control’s image directly (a texture rect?) after saving; I don’t see the need to load it back in. When starting the game? Sure, load it.

I don’t know where you’re saving the image to either; inside the file system (res://), hence the reimport? Perhaps reconsider this and use user:// or the OS paths instead (tough to follow with just snippets of code).

I’m using load() because it was an PNG. And I’m using like the path (a String) to load the image. It’s something like a preload, but I want it to only load that image when I needed (to save memory)

Change it directly

Yeah I’m using the rect texture for it. But the directly that you mention, by using something like this right?:

#it just a example code, I reference the rect texture node of course
Var rect: RectTexture = RectTexture.new()
rect.texture = load(path) #using load instead of preload

The first time the application is running it’s load the texture as good. But when it get replace by the new one (in runtime) it doesn’t refresh it like I tell you above.

For the path, yes I’m using the globalize_path() so it can convert the res:// or user:// to the absolute path (I’m saving the file close to the game.exe, for modder reason so it easy to access)

Hmm perhaps I made a mistakes on my code or something. Maybe it worth to take a look. Thanks again man, I’ll will message you if I made some progress for it.

Oh btw, do you know how to use abstract class in script? My code still isn’t working yet, Maybe I can learn more or two from that if you know how to do that of course (I search everywhere for an example but still bummer)

This might be because the old file is still cached since resources are usually only loaded once, you can force it to load without considering the cache.
load(path: String, type_hint: String = “”, cache_mode: CacheMode = 0) (try 0 and 2)

1 Like

Wow Thank you so much, when im looking at the documentation yesterday, i found the one that can be used in runtime and externally too ImageTexture.Documentation

idk for the exported one, but when it running in the editor one it’s work like a charm, this is my code right now is something like this if someone want to know:

func image_loader() -> void:
        ... Other Func ...

	if OS.has_feature("editor"):
		var image = Image.load_from_file(image_random)
		var texture = ImageTexture.create_from_image(image)
		project.thumbnail.texture = texture
	else:
		project.thumbnail.texture = ResourceLoader.load(image_random, "", 2)

       ... Other Func ...

I think my code is too oversight, maybe i don’t need to used the “ResourceLoader.load”. But hey, Right now It’s working like a charm in the editor runtime. So Thanks a lot yall!

1 Like