Need Help: Load Image Then Draw Text To The Image Then Create Sprite With Image & Text?

Godot Version

v4.5.1.stable.official [f62fdbde1] (Linux)

Question

Using GDScript, is it possible to do the following?

  • Load image then draw text to the Image then create sprite with image & text

The above would be done one time at application start.

We want to redo our block display system in our current project: “NumbersFall 110%”.
Also, after above is complete, it will be used in our next Godot project: “LettersFall 110%”.

Let us know - code sample would be very helpful…

Yes, use the Image class to load the image, then use ImageTexture to turn it into a Texture you can assign to a sprite.

Hi,

How would I draw text onto the new “ImageTexture” ?

Do you have to ‘draw’ it on the texture?

I checked your games. I think you can just simply use a Label Node, that is a child node of your ‘box’ texture (Sprite2D) . And you can easily change the text on the Label

I would like to combine an image with a text over it, is this technically possible in v4.5.1?

You could render the label into a SubViewport (with transparent BG) to get its image, then use Image.blend_rect() to blend both images together.

Something like that:

	await RenderingServer.frame_post_draw
	
	var image := Image.load_from_file(...)
	var label_image := get_viewport().get_texture().get_image()
	
	image.blend_rect(label_image, Rect2i(Vector2i.ZERO, label_image.get_size()), Vector2i.ZERO)
	
	texture = ImageTexture.create_from_image(image)

Personally I would just pre-render all the images beforehand

1 Like

Hi,

Still need some help with above…

We have just now uploaded the project GDScript source code to GitHub.

Sprite class declaration below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L51

Text class declaration below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L74

Sprite image loading below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L178

Sprite drawing below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L501

Text drawing below:
https://github.com/savantsavior/numbersfall/blob/main/project_numbersfall/VisualsCore.gd#L550

Any help incorporating above thread post into our framework would be appreciated!

Hi,

Looked around and found below example which compiles, but crashes out when run?
If someone could suggest a fix to below GDScript source code then that would be great.

	# Load two images to combine into one image
	var img1 = load("res://media/images/gui/Button2.png")
	var img2 = load("res://media/images/gui/Exit2.png")

	# Blend img2 onto img1
	img1.blend_rect(img2, Rect2i(Vector2i.ZERO, img2.get_size()), Vector2i.ZERO)
	# ^--- Invalid call. Nonexistent function 'blend_rect' in base 'CompressedTexture2D'.

	# Convert back to texture
	img1 = ImageTexture.create_from_image(img1)

We need above to work for our new: “LettersFall 110%” word spelling game.
Really stuck on this, please help if you can!

	var img1 = load("res://media/images/gui/Button2.png")
	var img2 = load("res://media/images/gui/Exit2.png")

Loading an image file returns a CompressedTexture2D type.
That type does not have blend_rect() as a method.
You need to convert from CompressedTexture2D to Image.
Then you need to place your blended image texture onto a node that can accept a texture. An Image does not take a texture it can only return one. (I don’t know the ins and outs of why)
In this example I use the blended texture as the texture for a TextureRect.

@onready var texture_rect: TextureRect = $TextureRect

func _ready()->void: 
	var c_img1:CompressedTexture2D = load("res://bishop.png")
	var c_img2:CompressedTexture2D = load("res://knight.png")

	var b_img:Image = c_img1.get_image() # image to blend into 
	var img2:Image = c_img2.get_image()  # image blending into it

	b_img.blend_rect(img2, Rect2i(Vector2i.ZERO, img2.get_size()), Vector2i.ZERO)
	texture_rect.texture = ImageTexture.create_from_image(b_img)	

Depends how you import it. If you import it as an Image (preset in import options) - it’ll return an Image object.

Image object represents bitmap data stored in the regular ram , while Texture object represents bitmap data stored in video ram (and ready for drawing by the GPU). The former is accessible by the CPU. That’s why you can do bit-blitting operations with it which are done by the CPU.

Converting a Texture to an Image (or vice versa) entails bitmap data transfer between video ram and regular ram which is a costly operation.

1 Like

It may be worth mentioning that it’s a quite a bit less costly on Mac systems with unified memory.

The cost is really irrelevant if you’re not doing it every frame. If you are doing it every frame - you shouldn’t, unified memory or not.

I appreciate the posts, but this is not solved…

Does Godot v4.5.1+ have a GUI system?

Like how would you in GDScript source code do the following:
Create button with image, add text to new button, and make the button with text scale down when clicked

Thinking ahead of Localization support:
Not all languages use the American English 26 letters.

Hand drawing all the characters is not the way to go here.

If you have something to add, post it here, thanks!

IMHO Your questions are a little bit too broad
Read the following, and if you have additional questions please ask.

GUI:

Localization:

You actually got several workable solutions.