Choosing where imageData:encode saves

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
fmra
Prole
Posts: 11
Joined: Fri Nov 29, 2013 9:39 pm

Choosing where imageData:encode saves

Post by fmra »

Is there a way to do this? I dislike the love.filesystem restrictions, so I use lua io for file placement, but I can't figure out how to control the save location for pictures exported with imageData:encode, or if there is a way to do it.

Is there another way to export png images, a library or method? I'm very close the finishing the program I'm using it in and would rather not have to back edit it all to work with love.filesystem.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Choosing where imageData:encode saves

Post by davisdude »

I hate to be the bearer of bad news, but io. functions are very platform dependent and (typically) have to be coded differently for each OS. That being said, you can use love.filesystem.setIdentity, but that only changes the name of the folder. I'm assuming you're making an image editor of some sort or something. One possible solution is to use love.system.openURL to open the folder for the user. That way, they can copy and paste the image.
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
fmra
Prole
Posts: 11
Joined: Fri Nov 29, 2013 9:39 pm

Re: Choosing where imageData:encode saves

Post by fmra »

Not bad news, since I'm not writing it to be mobile or mac, just Windows. As you said, setIdentity only changes the cosmetic name of the folder in %AppData%, so it of no use.

I'm writing a small, very specific, database tool and I'm trying to get it to export generated graphs and charts as PNG images to be used in generated reports or Word.

I'll try using openURL, as that seems like a usable solution. Thank you so much davisdude. =)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Choosing where imageData:encode saves

Post by davisdude »

Well that's good. Glad I helped you. :)
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
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Choosing where imageData:encode saves

Post by Positive07 »

Code: Select all

--save your image as temp.png
--Read the image in the appdata folder
local r = love.filesystem.read("temp.png")
--Open the file where you want to save your image in write-binary mode
local f = io.open("yourimagename.png","wb")
--Write the image to this file
f:write(r)
--Delete the temporary image
love.filesystem.remove("temp.png")
This code takes LOTS of time to execute, imagine:
  • Writing an image to the appdata folder
  • Reading the file and storing all the information in memory
  • Writing lots of content from the memory to a file
And to add to that, the operations happen in the hard disk drive which is WAY slower than RAM

Also images are huge chunks of data, if you dont want to waste memory then you should do something like:

Code: Select all

local size = love.filesystem.getSize("temp.png")
local chsize = 1024 --Chunk size
local iter, endch = math.ceil(size/chsize), size%chsize --Number of iterations and size of the last chunk

local f = io.open("yourimagename.png","w+b")
local temp = love.filesystem.newFile("temp.png","r")

for i = 1, iter do
    if i == iter then ch = endch else ch = 1024 end
    temp:seek(1024 * (i-1)) --Goto the position we want to read
    local data = temp:read(ch) --Read a chunk of data
    f:write(data) --Write it to the file
end
--Close all the files and delete the temporary file
temp:close()
f:close()
love.filesystem.remove("temp.png")
This allows you to break the file into chunks and read them, also with this you can monitor the progress and maybe even add a progress bar representing the file being copied.

You could place this in a thread so that it wont stop your game/app.

Still [wiki]love.system.openURL[/wiki] is better but this is just another method
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
User avatar
Ref
Party member
Posts: 702
Joined: Wed May 02, 2012 11:05 pm

Re: Choosing where imageData:encode saves

Post by Ref »

Hi Positive07!
Tried you image copying suggestion from straight Lua and ran into some problems.
Came up with the following (which works):

Code: Select all

local srcName = '"some image file name"
local srcImage = io.open( srcName, "rb" )
local dstName = "new name for image created"
local dstImage = io.open( dstName, "wb" )
local size = srcImage:seek( 'end' )
local chsize = 1024
local iter = math.floor(size/chsize)
local endch = size%chsize
for i = 1, iter do
   if i == iter then ch = endch else ch = 1024 end
   srcImage:seek( 'set', 1024 * ( i-1 ) )
   local data = srcImage:read( ch )
   dstImage:write( data )
   print( chsize * i..' bytes read')
end
srcImage:close()
dstImage:close()
Got confused by your use of 'temp' == 'source image' and 'f' == 'new image'.
Wouldn't work unless I changed 'ceil' to' floor' and added 'set' to seek.
Is Love that different?
I usually use the Love file system.
User avatar
Positive07
Party member
Posts: 1014
Joined: Sun Aug 12, 2012 4:34 pm
Location: Argentina

Re: Choosing where imageData:encode saves

Post by Positive07 »

Ref wrote:Hi Positive07!
...
Got confused by your use of 'temp' == 'source image' and 'f' == 'new image'.
Wouldn't work unless I changed 'ceil' to' floor' and added 'set' to seek.
Is Love that different?
I usually use the Love file system.
It's really probable that my code was wrong, I didnt test it, anyway a pure io implementation doesnt sound like the best idea (finding the source image may get a little bit complicated, also the file path may be protected with admin permissions) but it is possible.
You could replace the filesystem API with [wiki]ImageData:getString[/wiki] and jump the step of reading the file and saving the image to the save directory. But I'm not sure that it works.

If you floor the iterations then you'll miss an iteration, for example if I have a 1.5Kbytes files and I am splitting it in 1Kbytes chunks
If I do 1.5/1 I get 1.5, If I floor the result I get 1.
End chunk will be 0.5, so the foor loop will be

Code: Select all

for i=1,1 do
    if i = 1 then ch = 0.5 else ch = 1 end
    --Copy the chunk
end
So I will just get 0.5Kbytes copied also if you try to copy more bytes than what exists in the file then there will be no problem, cause it will read as many bytes as it haves available, and if you are at the end then that is 0.
So I think math.ceil is better

Seek works a little bit different from io in comparison to love, there are no "set" or "end" keywords, just a number.

Also when opening a file with io I open it for write/append/binary, so that no info is deleted when writing, I think that behavior is preferred but I'm not sure.
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Post Reply

Who is online

Users browsing this forum: darkfrei, Google [Bot] and 4 guests