Manipulating FileData, ImageData, external images

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Abisso
Prole
Posts: 5
Joined: Sun Apr 13, 2014 7:47 pm

Manipulating FileData, ImageData, external images

Post by Abisso »

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:

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")
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:

Code: Select all

		savedir = love.filesystem.getSaveDirectory()
		savedfile = savedir.."/outimage.png"
		outputfile = io.open(savedfile, "wb")
		outputfile:write(filecontent)
		outputfile:close()
instead of:

Code: Select all

		outputfile = love.filesystem.newFile("outimage.png", "w")
		outputfile:write(filecontent)
		outputfile:close()
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:

Code: Select all

outputfile:write(filecontent)
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.
Abisso
Prole
Posts: 5
Joined: Sun Apr 13, 2014 7:47 pm

Re: Manipulating FileData, ImageData, external images

Post by Abisso »

I apologize for bumping and I understand it's against the rules; but honestly, as there are several new posts a day I doubt this post would have ever received any more attention if I didn't.

If there's a particular reason why I haven't received an answer yet (maybe I broke some rules, or overlooked something) please just tell me and I'll try to fix my original post. I apologize if I made some mistake. Thanks
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Manipulating FileData, ImageData, external images

Post by davisdude »

Sorry for not responding. This forum does get pretty swamped with problems.
I'll give it my best shot:
Abisso wrote: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).
Hello! Honestly, I would go to 0.9.1 because it fixes several bugs, but feel free to stay at 0.9.0 if you'd like. That's just an opinion.
Abisso wrote: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.
I'll try my hardest, but I can't promise anything. (SARCASM!)

You have an interesting predicament. From my understanding, you want to access files outside of the file itself. You would be correct in using the io. Lua library. love.filesystem cannot and will not go outside of the scope of LÖVE (as far as I know). Your function actually works correctly, problem is that it's being made in "C:\Users\YOUR USERNAME\AppData*\Roaming\LOVE\Maze Creation\"
*This folder is not visible unless you set your preferences to see hidden files.)
Abisso wrote:1. This solution is, to use an understatement, "inelegant".
I wouldn't call it "inelegant". It's probably not optimal, but unless you want to get in to C*, it's the best you can do, I think.
*NOTE: I haven't tested this. If you like, let me know how it works!
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()
I ran into this problem when I was testing, too. For some reason, the io. functions won't make the image correctly...
Abisso wrote: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?
I'm not sure, but I DO know that anything with b at the end opens the binaries, which isn't done by Lua by default. However, since LÖVE is designed to be cross-platform, and some platforms require binaries, I would assume that it does add the b by default.
Abisso wrote: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.
Well, from my investigation, it's not possible. ImageData is the raw form of the image. FileData is the same, only for files.

Sorry for not being too helpful. I'll do some more investigating and see what I can come up with.
(Oh, by the way, as far as I can tell, no rules were broken, your question was just too intimidating :oops: )
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Abisso
Prole
Posts: 5
Joined: Sun Apr 13, 2014 7:47 pm

Re: Manipulating FileData, ImageData, external images

Post by Abisso »

Hello there.

Thanks a lot for the reply. I have to admit I feared that the lack of answers might have depended on the nature of the questions themselves; but I was also pretty sure there must have been someone knowledgeable enough to give me some hints.
I greatly appreciate your attempt, and you definitely helped me: so you have my gratitude.

Also, you understood perfectly what I was going to do, despite the lack of a .love attachment. I want to clarify why I didn't add such a thing: I'm some kind of freak when it comes to code, and I don't like to share unpolished, messy files; but I always end up creating the entire project as a total mess, before entering an optimization&cleaning stage. Also, this is already quite a complex project, but the relevant portion of it was just a few lines. I intend to share the result with the community once it's complete, however.

There's no particular reason why I'm using 0.9.0 instead of 0.9.1: I see it went out exactly the day after I got into Lua, and so I wasn't even aware of it. I'll check the list of changes more thoroughly and see if it's worth upgrading; for the moment I see the very interesting addition of a "srgb" parameter to love.graphics.isSupported. Something I was in need of!

There is one thing about your post that I didn't understand:
Your function actually works correctly, problem is that it's being made in "C:\Users\YOUR USERNAME\AppData*\Roaming\LOVE\Maze Creation\"
*This folder is not visible unless you set your preferences to see hidden files.)
I'm aware that the function works and that files are being created there: as a matter of fact I fetch them from that folder when I use them as sources for loveframes' functions. I was surprised as well that specifying no path at all (image1:SetImage("outimage.png") instead of image1:SetImage("savedir.."/outimage.png")) looked for the files there, but it apparently does. I suppose LOVE looks into both the main folder and the Save folder (probably in this order) whenever no path is specified.
But I'm not sure if this is what you meant when you said "the problem is..."

About the binary attribute, we seem to agree: it was merely a matter of curiosity and desire to understand inner mechanics, by the way. I have to add that with io.open functions the "rb" and "wb" attributes are absolutely necessary to recreate a working image file (at least with .png files, but I suppose with all the other formats as well). The io.open functions do manage to create a working image file anyway: the only thing that doesn't seem to work is to create it into LOVE's save directory. But I don't understand if this is due to errors of mine when trying to access the path, or if there is some kind of limitation / conflict which I haven't investigated thoroughly enough.

About a possible use of ImageData / FileData, it's a shame! It looked like it could be a reasonable path to explore, but I'm gonna take your word for it and trust your previous investigations.

And for what concerns luafreeimage... can you give me a bit more insight about what it is? I can't figure it out and I haven't been able to find any post / manual / discussion about it.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Manipulating FileData, ImageData, external images

Post by davisdude »

Abisso wrote:There is one thing about your post that I didn't understand:
Your function actually works correctly, problem is that it's being made in "C:\Users\YOUR USERNAME\AppData*\Roaming\LOVE\Maze Creation\"
*This folder is not visible unless you set your preferences to see hidden files.)
I'm aware that the function works and that files are being created there: as a matter of fact I fetch them from that folder when I use them as sources for loveframes' functions. I was surprised as well that specifying no path at all (image1:SetImage("outimage.png") instead of image1:SetImage("savedir.."/outimage.png")) looked for the files there, but it apparently does. I suppose LOVE looks into both the main folder and the Save folder (probably in this order) whenever no path is specified.
But I'm not sure if this is what you meant when you said "the problem is..."
I thought that you couldn't access it because of this:
Abisso wrote: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:

Code: Select all

outputfile:write(filecontent)
But then again, I misread it (it was also 1:00 A.M. where I live, so I wasn't thinking all that clearly :| ).
So, that's what I meant when I said "the problem is." I thought you couldn't access the file. By the way, I made a typo. I accidentally put "LOVE\Maze Creation\", which is incorrect. As I'm sure you've figured out, it goes based on the name of your file. I just forgot to remove that part after copying then pasting.
Abisso wrote:About the binary attribute, we seem to agree: it was merely a matter of curiosity and desire to understand inner mechanics, by the way.
Ah. Yes, I think that is what they've done, but you would have to ask a developer about that (Rude, etc.).
Abisso wrote:I have to add that with io.open functions the "rb" and "wb" attributes are absolutely necessary to recreate a working image file (at least with .png files, but I suppose with all the other formats as well).
It seems to me that is correct, as well. Without that it just gave me the extension.
Abisso wrote:The io.open functions do manage to create a working image file anyway: the only thing that doesn't seem to work is to create it into LOVE's save directory. But I don't understand if this is due to errors of mine when trying to access the path, or if there is some kind of limitation / conflict which I haven't investigated thoroughly enough.
You can get LÖVE's default save directory by using the function love.filesystem.getSaveDirectory and then using the io.open with the 'wb' selected. I assume this is the save directory you are talking about. When trying to make a file inside the folder with all the other contents, however, proves to not work.
Abisso wrote:About a possible use of ImageData / FileData, it's a shame! It looked like it could be a reasonable path to explore, but I'm gonna take your word for it and trust your previous investigations.
Again, I'm not totally positive on this issue: you may want to employ the usage of a developer.
Abisso wrote:And for what concerns luafreeimage... can you give me a bit more insight about what it is? I can't figure it out and I haven't been able to find any post / manual / discussion about it.
I've never used it either. I just thought it might be handy, if you couldn't get anything that suited your needs.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 2 guests