+3 votes

I'm trying to programmatically load an Image and create an ImageTexture from it. I want to do this so that I can programmatically modify the pixel data of the Image. Here's some sample code from my TextureRect:

func _ready():
  var image_texture = ImageTexture.new()
  image = Image.new()
  image.load('res://path/to/file.png')
  image.lock()
  image_texture.create_from_image(image, 0)
  self.texture = image_texture

This works fine when I run the game from the editor. However, I get a warning in the debugger that says "Loading resource as image file, this will not work on export." And thus, when I export to Android, these images are not loaded.

I do not want to use the load() function (as suggested here), because that gives me a StreamTexture and doesn't allow me to manipulate pixels.

I've found a few Github issues about this:
- https://github.com/godotengine/godot/issues/20972
- https://github.com/godotengine/godot/issues/18638
- https://github.com/godotengine/godot/issues/15380
but none of them seem to provide solutions for this issue.

So - is there a good way to make this work for exported games?

in Engine by (32 points)

3 Answers

+5 votes
Best answer

Ok, this is actually pretty simple. The basic idea is that instead of using Image.load to load an image, you can use load() and then call get_data().

var stream_texture = load('res://path/to/file.png')
var image_texture = ImageTexture.new()
image = stream_texture.get_data()
image.lock() # so i can modify pixel data
image_texture.create_from_image(image, 0)
by (32 points)

Thanks, this is working.

0 votes

I had a similar problem, in my case it was when exporting to Windows, have you tried unchecking the option ’Export whit debug’ at the last step of exporting? (below the text box where the name of the .apk file is placed)

You could also try removing the "res://" from the file directory

like this = "res://sour/img.png"
to this = "sour/img.png"

Good luck

by (18 points)

Thanks for the help.

I tried removing the res:// from the file path. Interestingly, it got rid of the debugger warning, but the images still don't show up in the exported version of the game.

I haven't tried exporting a "release" version of the APK yet, but if that's necessary, it seems like there's a bug. I think there should be a better way?

0 votes

I have a similar situation where I asked in here:
https://godotengine.org/qa/49332/how-to-make-a-new-image-with-small-file-size

The related part is the ans by Zylann.

So, I am not sure if it is working for you as I am just a beginner.
But I think if you import you image as an Image (not Texture) you could do something like this:

var image = load("res://path/to/file.png")  # this should give you the Image
image.lock()
{do the pixel things}
image.unlock()
var image_texture = ImageTexture.new()
image_texture.create_from_image(image)
self.texture = image_texture

By not importing as Texture( but Image), GD.load() will not give StreamTexture. Instead, it gives an Image. That's what I think. Not so sure if I understand all things correctly.

by (58 points)

Thanks Gary! This isn't completely correct (well, at least not for Godot Engine v3.1.1), but it helped me debug :) I'll update my post with what worked for me.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.