But it will only load the texture the way it was when I hit play whenever I try to update it; it doesn’t load the edited image (it’s like the file is cached as it was when it was originally loaded and whenever I try to re-load it it’s loaded from cache instead of from the actual file)
The editor itself seems to update the file whenever I begin and end a playtest.
Firstly, use user:// for editing images while running.
Secondly this gets messy due to file locking which does not seem to be gracefully handled.
For example, the below script I just hashed up ‘works’, but I can’t seem to catch the C Errors it prints to console due to trying to load a partially complete image.
Hopefully a good place to start though:
var filepath := "user://picture.png"
var filesize:=0
func _physics_process(_delta):
if FileAccess.file_exists(filepath):
var file = FileAccess.open(filepath, FileAccess.READ)
if file and file.get_open_error() == OK:
var modifiedsize = FileAccess.get_modified_time(filepath)
if filesize != modifiedsize:
print("File size changed, attempting to load image...")
if file and file.get_open_error() == OK:
var buffer = file.get_buffer(file.get_length())
if buffer.size() > 0:
var image = Image.new()
var error = image.load_png_from_buffer(buffer) # Arbitrarily seems to fail with uncaught C errors. Feels like a bug tbh
if error == OK and image.is_empty() == false:
print("Image loaded and valid")
$TextureRect.texture = ImageTexture.create_from_image(image)
filesize = modifiedsize
else:
print("Error: Image is not valid or could not be loaded.")
file.close()
else:
print("File is currently being written to or inaccessible.")
and how it looks:
I mean why is Image.is_valid() not exposed to gdscript >.>
Wait my code was fine, i was just screwing up because of a bad if statement
Man, I spent so long overlooking it.
I basically just had to change if texture.resource_path == BMP to
var imgpath: String = texture.resource_path
...
...
if imgpath == BMP:
Because apparently the texture.resource_path changes when I reload the image, even if it shouldn’t cuz it’s the same image in the same location.
I’m just gonna accept ur answer though cuz it was fairly good.
Your error is probably because you’re running it on every physics frame, so therefore it is running while the image is being saved, when it is being saved the image file may be incomplete for some milliseconds and thus it will read as corrupt.
Some discoveries:
load("path") only works for files under res://, it doesn’t work for files under user://
Use a timer to wait an arbitrary amount of time (maybe 2 seconds) before attempting to change the image.
But your current approach is fine imo. You get an error, but you handle it just fine, I’d say just don’t let it bother you (maybe see if there’s a way to suppress errors for this particular code). I’d be more worried about streamlining the code cuz those are some deeply nested if statements right there so many validity checks, and most of them not cheap.
Oh I don’t need to solve it, I wrote that code purely to answer this post because I thought it would be fun.
The timer is not going to prevent the error though, it would just make it occur less frequently and make the third party app to Godot refresh slower. The nested IFs were me trying to get to the bottom of the error due to simultaneous file access (i.e. trying to load the image in Godot before GIMP has finished saving it).
I’ve logged a github issue as I think it’s actually a bug in how it’s being handled in core, that is var error = image.load_png_from_buffer(buffer) should NOT cause a C++ stderr under any condition which is what seems to be happening.
I really wonder if there’s a way to make this code work with texture.load() though.
The reason I’m trying to do it this way is becase I have some code to re-scale SVG images, and I wanted to try to optimize it by storing the scaled images in a cached PNGs or BMPs, then loading the textures from those cached files in the hopes that if the textures are being loaded from the same file they would share memory space (to prevent duplicate memory storage of identical textures) as opposed to from buffers which i’m pretty sure is creating unique instances of each ‘image created from buffer’ even if they are identical. I could be wrong though, I’m making a lot of assumptions.