Manipulating FileData, ImageData, external images
Posted: Sun Apr 13, 2014 9:29 pm
Hello there, LOVE 0.9.0 user on Windows XP SP3 here (but just because my Linux Distro is too old and messy atm to support that Love version).
Though I've got some experience with coding and game-making, I've only recently started dealing with Lua and LOVE so please forgive me if what I'll be asking looks stupid or inappropriate.
First of all, let's share some light on what I'm trying to do and why I need to do what I'm trying to. Basically, what I want to do is build a launcher for a non-Lua application (an .exe) that allows also some setup functionalities and extras. I've managed to achieve the most part of that and gave it a fine look mainly thanks to Loveframes.
Anyway, one of the "extras" I talked about would require accessing to external image files and display them inside the love application. The reason for this need is that those image files get created by the game whose the lua app is the launcher of. So in no way I can put those files inside the .love archive nor in the love save directory. I'm clarifying this because I know I'm not the first one that's interested in manipulating external files, and I want to show I'm aware of (and understand) LOVE's limitations. In my particular case, there's no way I can create those files inside the "love-writeable" folder nor package them before distributing the love app.
That said, I managed to find a workaround, which is the following:
resources_dir holds the path of the directory where the images are stored; imagefile holds the name of the image file I want to use (I'll use an array in the actual implementation, but this is just a working prototype); image1 is an Image object created with the library Loveframes, and the function SetImage(filename) simply sets the image displayed by the object.
So, basically I use the io functions to access the image files, create a copy in love's save directory and then use that duplicate to do what I need to do. Then I remove the duplicate.
There are several problems / doubts though:
1. This solution is, to use an understatement, "inelegant".
2. I use a mix of basic lua io functions and love io functions, cause for some reason I can't seem to recreate the copy by using something like:
instead of:
Anyway I can recreate the file elsewhere by using the io.open function, it just doesn't seem to work in love's save directory. The error message says that outputfile doesn't exist and so of course the process fails at the line:
I also noticed I need to use the "wb" parameter with io.open() to obtain a non-broken image file (using "w" produces a broken image file), but since using "w" with love.filesystem.newFile() works perfectly I suppose LOVE's "w" parameter is equivalent to "wb" and not to "w". Is that so?
My feeling is that there is a way to achieve similar and probably more elegant and fast results by manipulating FileData and ImageData from the file that's been read, and using that instead of a path to an image file. Problem is I didn't manage to achieve this, and to be frank I didn't even manage to understand fully what FileData and ImageData are. I'd appreciate some words of wisdom about them and someone experienced enough to know if my hypothesis is realistic or not.
Anyway, even if it's not, I'm more than happy to share my crappy-but-working solution with this nice community. I needed the entire afternoon to figure it out and searching the forums and elsewhere didn't bring up any solution, so I hope other people will benefit from this topic. I'm more than sure that this kind of functionality is not that uncommon as a need for an app; and even if workarounds and alternative solutions are fine in most cases, there are some where you definitely need to access external resources.
This method of course applies also to other media types (music files, for example).
Thanks for reading.
Though I've got some experience with coding and game-making, I've only recently started dealing with Lua and LOVE so please forgive me if what I'll be asking looks stupid or inappropriate.
First of all, let's share some light on what I'm trying to do and why I need to do what I'm trying to. Basically, what I want to do is build a launcher for a non-Lua application (an .exe) that allows also some setup functionalities and extras. I've managed to achieve the most part of that and gave it a fine look mainly thanks to Loveframes.
Anyway, one of the "extras" I talked about would require accessing to external image files and display them inside the love application. The reason for this need is that those image files get created by the game whose the lua app is the launcher of. So in no way I can put those files inside the .love archive nor in the love save directory. I'm clarifying this because I know I'm not the first one that's interested in manipulating external files, and I want to show I'm aware of (and understand) LOVE's limitations. In my particular case, there's no way I can create those files inside the "love-writeable" folder nor package them before distributing the love app.
That said, I managed to find a workaround, which is the following:
Code: Select all
local inputfile = io.open(resources_dir..imagefile], "rb")
filecontent = inputfile:read("*all")
inputfile:close()
outputfile = love.filesystem.newFile("outimage.png", "w")
outputfile:write(filecontent)
outputfile:close()
image1:SetImage("outimage.png")
love.filesystem.remove("outimage.png")
So, basically I use the io functions to access the image files, create a copy in love's save directory and then use that duplicate to do what I need to do. Then I remove the duplicate.
There are several problems / doubts though:
1. This solution is, to use an understatement, "inelegant".
2. I use a mix of basic lua io functions and love io functions, cause for some reason I can't seem to recreate the copy by using something like:
Code: Select all
savedir = love.filesystem.getSaveDirectory()
savedfile = savedir.."/outimage.png"
outputfile = io.open(savedfile, "wb")
outputfile:write(filecontent)
outputfile:close()
Code: Select all
outputfile = love.filesystem.newFile("outimage.png", "w")
outputfile:write(filecontent)
outputfile:close()
Code: Select all
outputfile:write(filecontent)
My feeling is that there is a way to achieve similar and probably more elegant and fast results by manipulating FileData and ImageData from the file that's been read, and using that instead of a path to an image file. Problem is I didn't manage to achieve this, and to be frank I didn't even manage to understand fully what FileData and ImageData are. I'd appreciate some words of wisdom about them and someone experienced enough to know if my hypothesis is realistic or not.
Anyway, even if it's not, I'm more than happy to share my crappy-but-working solution with this nice community. I needed the entire afternoon to figure it out and searching the forums and elsewhere didn't bring up any solution, so I hope other people will benefit from this topic. I'm more than sure that this kind of functionality is not that uncommon as a need for an app; and even if workarounds and alternative solutions are fine in most cases, there are some where you definitely need to access external resources.
This method of course applies also to other media types (music files, for example).
Thanks for reading.