Downloading an image and adding it dynamically to a texturerect doesn't work

Godot Version

4.4

Question

Hey peeps, this is driving me crazy. I am trying to migrate an existing add-on I developed for Godot 3.x into Godot 4.x

I’ve used the automatic migration and tweaked to fix the things that didn’t work automatically, all good until this point.

However something is not working and it doesn’t make sense.

Part of the addon is to download an image, and render inside a TextureRect. The code worked just fine in Godot 3.x, but in Godot 4x, while there’s no error, the image just…doesn’t display. Everything is processed as expected by the code, the image is processed, the texture is created and added to the TextureRect but the actual runtime window doesn’t display the image

I check in the remote tab, and the new texturerect is there, the texture is there. It just doesn’t display it. The relevant code is

func prepare_aitexture(imgbuffer: PackedByteArray, img_dict: Dictionary, timestamp: int) -> AIImageTexture:
	var image = Image.new()
	var error = image.load_webp_from_buffer(imgbuffer)
	if error != OK:
		var error_msg := "Couldn't load the image."
		push_error(error_msg)
		emit_signal("request_failed",error_msg)
		return null
	var texture = AIImageTexture.new(
		prompt,
		imgen_params,
		img_dict["seed"],
		img_dict["model"],
		img_dict["worker_id"],
		img_dict["worker_name"],
		timestamp,
		control_type,
		image,
		img_dict["id"],
		async_request_id,
		img_dict.get("gen_metadata", [])
	)
	texture.create_from_image(image)
	texture.save_in_dir("/home/db0/tmp") # Debug
	latest_image_textures.append(texture)
	return texture

AIImageTexture is just an ImageTexture inherit with some extra attributes and the filesave methods.

As I have code to save the downloaded image, I used it to save the downloaded image as a .png to disk, and that worked as well. I can see the image is correctly downloaded.

So why doesn’t it display it?!

I’ve already tried switching to a standard ImageTexture, no change. I tried downloading a random .png image from the internet, same results. I’m really stumped!

how do you set the image texture to the texturerect?

you may want to update() it first before actually use it for your texture rect

i noticed this update() function doesn’t exist on godot 3.6, so that may be an extra step needed to do in Godot 4

ImageTexture.create_from_image() is a static function that returns an ImageTexture so it would be:

texture = ImageTexture.create_from_image(image)

Yesss! Thank you so much that was part of the puzzle. It does create some headaches, because in 3.x I was able to extend the ImageTexture to add some extra attributes and methods to it because 3.x worked by just making a .new(). But since 4.x expects to use create_from_image to initialize it, and that static func returns specifically a ImageTexture class, I can’t see how I can possible extend the ImageTexture class in 4.x.

Any suggestions?

Ah ok I think I found what I needed. In 4.x I just need to use set_image(image) to have the same functionality I had with create_from_image() in 3.x. This is now the working code

func prepare_aitexture(imgbuffer: PackedByteArray, img_dict: Dictionary, timestamp: int) -> AIImageTexture:
	var image = Image.new()
	var error = image.load_webp_from_buffer(imgbuffer)
	#var error = image.load_png_from_buffer(imgbuffer)
	if error != OK:
		var error_msg := "Couldn't load the image."
		push_error(error_msg)
		emit_signal("request_failed",error_msg)
		return null
	var texture = AIImageTexture.new(
		prompt,
		imgen_params,
		img_dict["seed"],
		img_dict["model"],
		img_dict["worker_id"],
		img_dict["worker_name"],
		timestamp,
		control_type,
		image,
		img_dict["id"],
		async_request_id,
		img_dict.get("gen_metadata", [])
	)
	texture.set_image(image)
	latest_image_textures.append(texture)
	return texture