Creating an imageSheet using an absolute path in desktop

matias.kiviniemi

I think you misread me.

I am not suggesting sharing data between live apps with symlinks and junctions. 

Nor am I suggesting that app data live anywhere but in:

  • Resource

  • Documents

-Temporary

I am also NOT saying you can use RGFiles to magically display images from locations not listed above.  (RGFiles is for manipulating files not displaying images).

I am saying

  1. During development if you want to maintain a common library of functions/modules where all projects link to the same single location, then use symlinks and junctions.

  2. Same statement for common repositories of images and assets.

  3. If you are making private tools for yourself or distrbuted outside official channels, there are ways to access files from other locations to copy them into your own or otherwise manipulate them.  (Again, not to display them unless you first copy them into system.DocumentsDirectory.)

  4. If you use symlinks and junctions Corona will treat those links as if the folders are part of the actual structure and copy those resources into the build/binary.

If I read it right, the original purpose of this post was to find a way to keep a common set of content, where the instances live in one place, but are accessible in multiple projects.

I assumed the purpose of this was to simplify development and to ensure changes made to a common file would be seen immediately by all projects.

I also assumed that once you went to build, you would want those files copied into the target binary/bundle.

If I have mis-read the original intent of this post then let me know.

PS - You mentioned adding new paths similar to system.DocumentsDirectory, system.ResourceDirectory, et al. except pointing to the desktop.  While you can submit a official feature request for this (http://feedback.coronalabs.com/forums/188732-corona-sdk-feature-requests-feedback), I don’t think it will get done any time soon as it competing against other higher priority items and opens a can of worms on permissions issues.

Can you provide a better description of what you’re trying to accomplish? What file paths you need access to? This thread is really hard to follow and figure out what the actual use case/end goal is.

Thanks

Rob

I’m sure we have different purposes but mine was to create an imageSheet from a PNG in system temp written by a Photoshop plugin. So I have two apps running in same computer but different environments that need to agree on an accessible folder with some consistent method that works on both Mac&Win. Previously it was just reading the TMP env variable which you have on both Win & Mac. Now I’ll likely be using system.TemporaryDirectory, change the plugin write there and handle the platform differences.

That said, I think there is a need for more general purpose roots as above. I.e. the core problem is that graphics.newImageSheet() takes a root and relative path. So it does not help parse user directory from env variables because you can’t pass that graphics.newImageSheet except with the “…/”-hack

Yes, we do have different purposes, but the solution is the same. Sorry to have hijacked this thread, but i think our problems have enough in common to not need another thread.

What i essentially need is to be able to load an image, anywhere on the disk. My app is a desktop (macOS and win) level editor. Imagine Gimp or Photoshop opening a png file. My app will come with bundled textures, but i want the user to be able to select their own textures from their own folder, so that their maps/levels can have their own personal look.

I can open json files with no problem since io.open can open absolute paths, and i can even execute os commands to get image files to my apps documents directory. I would just like to do it directly, by directly loading the image the user specified from the absolute path. that’s all. No extra files, no cleaning temporary directories, no extra junk.

I already have my own tools to do filesystem stuff, and already have enough experience with environment variables, i do not need any of those. (But it is cool you shared the info for others)

Since the thread title is “creating an imageSheet using absolute path in desktop”, i thought our problems were close enough. We both need a way to load images/sheets with an absolute path. So i already created the feature request and had already shared it, here is the link again.

As a recap:

  • The app is a desktop app, no iOS, no Android, no WP

  • I don’t need a folder to access a common set of content

  • I do need to load images from any place to show them to the user.

I think i could list at least a thousand desktop apps that can read any file on any disk, including Corona SDK, it can load my projects’ main.lua using relative paths.

It sounds like what you really need is a file picker.

I already have one (FIle picker). The path returned from it is an absolute path, which cannot be loaded by Corona directly: display.newImage(absolutePath)

Have you tried copying the file to system.TemporaryDirectory and opening it from there?

No.

Corona image assets can only be accessed from the system.* directories for that app/game:

https://docs.coronalabs.com/daily/api/library/system/index.html#constants

The resource directory is the default: https://docs.coronalabs.com/daily/api/library/system/ResourceDirectory.html

Dang, that’s going to be a problem…

If you have a local web server, can’t you just let your app download the images to the system.DocumentsDirectory and access them from there instead?

We actually do and that was the original solution :slight_smile: But when have a hundred of them, downloading adds up while sharing a folder is near instantaneous.

But I think I found a workaround. The system.TemporaryDirectory evaluates to the user temp directories in Win (AppData/…) and Mac (~/Library/Application Data/…). It works a bit differently in both (and in Simulator!), so it’ll need some platform specific code.

That said, I really think the system temp should be an option in Corona. It’s there for a reason and easy to find using environment variables.

If you’re on  a windows system, you can use mklink /j to create a Junction.

This is how I maintain a common source for my (upcoming) revamp of SSK in all my test projects:

-- 1. cd to the folder where you want the link (usually root of your game) -- 2. decide on a name of the folder (junction). Below it will be called ssk2 -- 3. Call mklink using form shown below to make junction -- Caution: Git tools generally treat this like a folder and copy the contents into the repository. -- So, if you're keeping these projects on a git and do not want the common folder(s) -- saved in the repository, add them to your ignore list. -- -- Ex: in my case, my projects with junctions all ignore the folder ssk2 -- to from mklink /j .\ssk2 X:\Work\00\_CurentProjects\Corona\SSK2\ssk2

I am having this problem as well. I am developing a desktop tool to create levels for other Corona games. A planned feature is that the user can select their own textures, which of right now, is not that simple to achieve. What i am doing to be able to load images and other stuff on other folders is using double dot, like so:

display.newImage("../../../myImage.png")

This sort of works if you get on what directory you are in, using system.pathForFile, and then parsing the string to know how many subdirectories there are until directory root. (Tested only on macOS)

It would be great if there was a constant like system.UserDirectory and system.RootDirectory.

You could also execute io.popen with native copy commands to get the assets to the temporary directory.

Creative :slight_smile: Does that work the same way in Win/OSX/Simulator? I agree, system.RootDirectory, system.GlobalTempDirectory, system.UserDirectory or system.ApplicationDirectory (%appdata% in Win, ~/Library/Application Data/ in Mac) would definately be needed for desktop

I have no idea, what i have tested on is on the simulator, for now. I don’t know if it will be the same for macOS, since apps are inside a container (Which is a folder). I will test that today, and come back with some results and code.

Please keep in mind that on device things are sandboxed and you cannot reach outside of your project. So doing:

local img = display.newImageRect("…/…/…/…/someimage.jpg")

won’t work on device if you’ve backed out of your project past your main.lua. Symlinks should work but the files have to be referenced from within the app’s project sandbox folder tree.

Rob

@rob: Are you saying that in general or for desktop also? This question was in the desktop app context and in my experience is that there is no OS-limit on accessing paths beyond the sandbox. I.e. you can for example give a path like c:\path\to\file to just standard lua io-library and it’ll read that just fine. Also reading/writing system temp is perfectly fine behaviour for a win32 / macOS (given the right entitlement) app.

macOS apps can be sandboxed depending on their entitlements and how they are deployed from the store. But in general Desktops potentially can access paths outside of the app.

But the problem of backing up a path using …/ is making a huge assumption on desktop’s that the app is going to be installed in a specific folder. Not everyone installs apps in /Applications on macOS or on C:\Program Files (x86)\YourCompanyName\YourAppName on Windows. If you use the …/ (Parent directory) multiple times you may not find yourself looking in the right place. If you want to use an absolute path you can do so unless as I mentioned above you deployed your macOS app in a sandboxed fashion.

On Mobile, you are sandboxed and certainly don’t have access to folders outside the sandbox (well, Android you can absolute path to public folders if you know the path). 

Yes, we are aware of that. What i am planning on doing, to be able to get the number of “…”, is to do a system.getPathForFile, on the apps root. That way, i can parse the string to see how many folders to get to the real root.

For example, i have a file inside my container: file.txt, i do a system.getPathForFile(“file.txt”), that gives me the full path of the file: “/Users/MyUser/Documents/Projects/TestProject/file.txt”. Now i can parse that string and i know that it has 5 folders. now to find a global file, say, on “/Users/MyUser/Desktop/other.txt”, i now know i must append 5 “…” to the path, like with a for. like so: “…/…/…/…/…/Users/MyUser/Desktop/other.txt” 

I am developing a desktop application, a level editor to be precise, which would never make it’s way to Android or iOS, not with the current design at least.

I know that this is not really necessary to open files with io.open, but for display.newImage and the other Corona APIs this does the trick. (on macOS simulator, at least)