How to properly import resource as an Image object

Godot Version

4.6.1.stable

Question

I’m trying to correctly load an image as an Image object, because I will need to make some manipulations to the image in the future.

At first, I had this code:

func reset_texture() -> void:
	SkinMaterial.albedo_color = main_color
	SkinDetailImage.fill(Color.TRANSPARENT)
	if FileAccess.file_exists(pattern_path):
		var second_color_img = Image.create_empty(256, 256, true, Image.FORMAT_RGBA8)
		second_color_img.fill(second_color)
		SkinDetailImage.blend_rect_mask(second_color_img, Image.load_from_file(pattern_path), Rect2i(0, 0, 256, 256), Vector2i(0, 0))
	SkinMaterial.detail_albedo = ImageTexture.create_from_image(SkinDetailImage)

It worked fine, but I get this warning:

WARNING: core/io/image.cpp:2766 - Loaded resource as image file, this will not work on export: ‘res://model/patterns/pattern2.png’. Instead, import the image file as an Image resource and load it normally as a resource.

So I try to use @GDScript.load() to load the desired file. It’s loaded as an ImageTexture, so I use Texture2D.get_image() as suggested in the ImageTexture documentation.

		SkinDetailImage.blend_rect_mask(second_color_img, load(pattern_path).get_image(), Rect2i(0, 0, 256, 256), Vector2i(0, 0))

It freezes for a while, which would be ok since it won’t run frequently. But as you can see on the screenshot, it doesn’t work.

How should I be importing these images in a manner that will continue to work on exported projects?

I do understand that as the code currently stands, I can achieve the same effect more efficiently using shaders. But this is just a base, I will be doing a lot more image manipulation than just applying a masked overlay.

Also maybe it’s worth mentioning, this script is running as a @tool right now because it facilitates testing.

I figured it out. Texture2D.get_image() was returning a compressed image.

The solution was just doing

pattern_image = load(pattern_path).get_image()
if pattern_image.is_compressed():
	pattern_image.decompress()

SkinDetailImage.blend_rect_mask(second_color_img, pattern_image, Rect2i(0, 0, 256, 256), Vector2i(0, 0))

You may want to import as image, not as a texture. That way the image won’t go automatically to the video ram.

I thought about using Image.load() but didn’t because it says this here:

Warning: This method should only be used in the editor or in cases when you need to load external images at run-time, such as images located at the user:// directory, and may not work in exported projects.

Is there another way to import it as Image?

Just use load(), but previously change the import preset to “Image” (and re-import), exactly as the engine warning you posted suggested.

1 Like

Ooh, I see. Thank you!