Difficulty when loading images from external source (SOLVED)

I’m experimenting with modding and I’m trying to import an image from the save location on Windows (C:/Users/[user]/AppData/Roaming/[appname]) called arrow.png. I’m using the Image loader extension but I’m having some difficulties.

2 Main problems:

  1. Whenever I use resource.set_texture(), it sets the texture without changing image size on a sprite
  2. When the sprite is already in the right dimensions (it’s default animation is set on the same image I’m trying to load), it doesn’t appear when I load it, just shows a black box smaller than the expected size.

I don’t have an image right now, but it’s a 100x100 black box with a white arrow pointing right.

This is the code:

--testlua.lua
function loadResources()
    local path = sys.get_save_file("mpcreator", "arrow.png")
    local f = io.open(path, "rb")
    local bytes = f:read("*a")
    f:close()

    local image_resource = imageloader.load{
        data = bytes
    }

    resource.set_texture(go.get("#sprite", "texture0"), image_resource.header, image_resource.buffer)
end


--test.script
function init(self)
    local script = sys.load_resource("/res/testlua.lua")
    local f = assert(loadstring(script))
    f()
    loadResources()
end

I tried it directly inside the test.script file and the same thing happened.

Any help is appreciated, thanks.

Does it need to be sprites? This is easier to do with GUI nodes.

Example of loading splash images for portals in our games.

Edit: I realize you meant to say supporting game modding so this may not be super helpful.

local IMAGE_GUI = ""

local sys_info = sys.get_sys_info()
local files = require("imports.files")
local TEXTURE_ID_1 = "TEXTURE_ID_1"
local TEXTURE_ID_2 = "TEXTURE_ID_2"

local function is_editor()
	if not (sys_info.system_name == "Windows" or sys_info.system_name == "Darwin" or sys_info.system_name == "Linux") then
		return false
	end

	if files.isdir("bundle_resources") then
		return true
	else
		return false
	end
end

local function load_image(self, image_to_load, texture_id)
	local extra_path = ""

	if is_editor() then
		extra_path = "../../"
	end	
	local dir1 = directories.path_for_file(extra_path .. image_to_load)

	if files.exists(dir1) then
		local f = io.open(dir1, "rb")
		local bytes = f:read("*a")
		local img = image.load(bytes)
		if not img then	return false end

		if self.texture_loaded[texture_id] then
			gui.delete_texture(texture_id)
		end
		
		if gui.new_texture(texture_id, img.width, img.height, img.type, img.buffer) then
			self.texture_loaded[texture_id] = true
			print("Attempting to set texture...")
			gui.set_texture(IMAGE_GUI, texture_id)
		end		
	end

	
		
end

local function load_image_1(self)
	print("Splash portals - loading image 1")
	load_image(self, "splash_portal_1.png", TEXTURE_ID_1)

end

local function load_image_2(self)
	print("Splash portals - loading image 2")
	if self.texture_loaded[TEXTURE_ID_1] then
		self.texture_loaded[TEXTURE_ID_1] = nil
		gui.delete_texture(TEXTURE_ID_1)
	end	
	load_image(self, "splash_portal_2.png", TEXTURE_ID_2)
end

function init(self)
	self.texture_loaded = {}
	IMAGE_GUI = gui.get_node("image")
	--print("Image loader ", msg.url())
	
end

function final(self)
	if self.texture_loaded[TEXTURE_ID_1] then
		gui.delete_texture(TEXTURE_ID_1)
	end
	if self.texture_loaded[TEXTURE_ID_2] then
		gui.delete_texture(TEXTURE_ID_2)
	end	
end

function update(self, dt)
	-- Add update code here
	-- Remove this function if not needed
end

function on_message(self, message_id, message, sender)
	if message_id == hash("load_image_1") then
		load_image_1(self)
	end
	if message_id == hash("load_image_2") then
		load_image_2(self)
	end	
end

function on_input(self, action_id, action)
	-- Add input-handling code here
	-- Remove this function if not needed
end

function on_reload(self)
	-- Add input-handling code here
	-- Remove this function if not needed
end


1 Like

Yeah, it has to sprites because the modding contains custom images for items. That’s why I’m using imageloader.load() instead of image.load() because I’m trying to set a texture for a sprite.

I’ve also trieda setting the image of a sprite from disk, but that throws an error saying something along he lines of go.set() failed with an error code of -10.

Do you think there is a way to save files to the Defold project during runtime? Because like, when I do os.execute("dir") all the project files show up. Is there a way?

I found out the problem:

I read a different post saying that since you’re changing the texture, the the image in it, the loaded image has to be the same size as the texture. The OG image was 100x100 but the atlas the sprite was using is 128x128 so I changed the image size and it worked fine.

In the future I will just make the image dimensions by a power of 2, just make some of the pixels transparent so it’s compatible.

3 Likes