Using Save() and exporting application macOS

I have used save() in my code to save images of the window to the sketch folder as a ‘screenshot’ function and have exported my program to an application.
When I run the application and tried to screenshot the image is not saved.

I have also tried saving the images to a data folder and adding a data folder to the application folder but this also doesn’t work.

Is it possible to save images from the application?

Were you able to resolve this?

It sounds like you might be trying to saving files inside the app itself. What OS are you building / testing on? Have you tried a relative path outside the sketch, or an absolute path like the user Documents folder?

Thanks for your reply, it works when I use an absolute path however doesn’t seem to work using a relative path. I will be distributing the app to other people so I don’t know how this will work if I can only use an absolute path? I am on macOS.

Here is a test sketch that may help you narrow down what is happening.

/**
 * SaveExport -- exported app saving path tests
 * 2020-04 Jeremy Douglass -- Processing 3.4 macOS 10.12
 * 1. a red image appears in the /data subfolder
 * 2. blue and green images appear in the same folder as the app
 * 3. yellow and cyan images appear in the folder above the app (../)
 */
void setup(){
  println(sketchPath());
}

void draw(){
  if(frameCount==1){
    background(255,0,0);
    saveFrame("data/red-data.png");
  }
  if(frameCount==2){
    background(0,255,0);
    println("green-inside.png");
    saveFrame("green-inside.png");
  }
  if(frameCount==3){
    background(0,0,255);
    println(sketchPath() + "/blue-abs-inside.png");
    saveFrame(sketchPath() + "/blue-abs-inside.png");
  }
  if(frameCount==4){
    background(255,255,0);
    saveFrame("../yellow-rel-outside.png");
  }
  if(frameCount==5){
    background(0,255,255);
    println(sketchPath() + "/../cyan-abs-rel-outside.png");
    saveFrame(sketchPath() + "/../cyan-abs-rel-outside.png");
  }
}

have you tried the java function…

String applicationPath = System.getProperty(“user.dir”);

This is a platform independent method so works on windows and mac.

You could print out the applicationPath to see where the application thinks its home is, I use it in PoShowTube to get to my data folder…

String dataFolderPath = System.getProperty(“user.dir”) + “/data”;

Thank you for this. I forgot to say I am using Python mode and have converted your code to Python which works when running it in Processing but doesn’t work when I export it to an app. It seems that the sketchPath() is not defined properly for the Python app as when I print it out it just returns ‘/’. I’m not sure why this is happening, do I need to set the sketchPath() somewhere?

Sorry I forgot to mention I am using Python mode, is there a Python equivalent to this?

not sure im afraid, theres this on stackoverflow

Okay thanks I’ll take a look

On Linux sketchPath() worked OK in the exported Python mode app. I’ll see if I can test on MacOS and get back to you.

image

UPDATE: On my MacOS I can run the same sketch but the exported app just won’t launch! :(((
SECOND UPDATE: Chosing the 'Add Java" option worked,

image

Looks like sketchPath() worked. Can you check if it is something else?

I’m not sure why but when I exported the app with ‘Full Screen (Present Mode)’ selected, sketchPath() didn’t work but when I exported the app without this chosen, it worked.
Thanks for your help!

Good that it helped!

Curious that you mentioned Full Screen (Present Mode) is behaving differently.
I think I should add this to:

It seems to work fine on my version, with the present mode bug fixed.

Tested with the following:

def setup():
    size(800,800)
    text(sketchPath(),20,20)
    
def draw():
    if (frameCount==1):
        background(255,0,0)
        text(sketchPath(),20,20)
        saveFrame("data/red-data.png")
    if (frameCount==2):
        background(0,255,0)
        text(sketchPath(),20,20)
        saveFrame("green-inside.png")
    if (frameCount==3):
        background(0,0,255)
        text(sketchPath(),20,20)
        saveFrame(sketchPath() + "/blue-abs-inside.png")

It works with and without present mode selected:

Mollys-iMac:MacOS molly$ find .. -name "*.png"
../Processing/green-inside.png
../Processing/blue-abs-inside.png
../Processing/lib/jycessing/splash.png
../Processing/data/red-data.png

I’ll add that the sketchPath() is INSIDE the app, so from the finder you have to Show Package Contents to find the saved files.

Considering your intended goal of exporting a distributable app, you might want to consider using selectFolder() instead of trying to find a path, so the user can select the save path themselves:

savedir = None
frame=0

def setup():
    size(800,800)
    selectFolder("Select a directory to save to", "fileSelected")
    
def fileSelected(selection):
    global savedir
    println(selection.getAbsolutePath())
    savedir = selection.getAbsolutePath()
    
def draw():
    # selectFolder is async so frameCount won't work
    global frame
    global savedir
    background(0)
    if savedir is not None:
        frame=1
    if (frame==1):
        background(255,0,0)
        text(savedir,20,20)
        saveFrame(savedir + "/data/red-data.png")
        frame+=1
    if (frame==2):
        background(0,255,0)
        text(savedir,20,20)
        saveFrame(savedir + "/green-inside.png")
        frame+=1
    if (frame==3):
        background(0,0,255)
        text(savedir,20,20)
        saveFrame(savedir + "/blue-abs-inside.png")
        frame+=1

Here’s another alternative that uses a platform independent way to generate a save path:

from os.path import expanduser

savedir = None
frame=0

def setup():
    global savedir
    size(800,800)
    savedir = getSaveDir()
    println(savedir)
    
def draw():
    # selectFolder is async so frameCount won't work
    global frame
    global savedir
    background(0)
    if savedir is not None:
        frame=1
    if (frame==1):
        background(255,0,0)
        text(savedir,20,20)
        saveFrame(savedir + "/data/red-data.png")
        frame+=1
    if (frame==2):
        background(0,255,0)
        text(savedir,20,20)
        saveFrame(savedir + "/green-inside.png")
        frame+=1
    if (frame==3):
        background(0,0,255)
        text(savedir,20,20)
        saveFrame(savedir + "/blue-abs-inside.png")
        frame+=1
        
def getOsVersion():
    ver = sys.platform.lower()
    if ver.startswith('java'):
        import java.lang
        ver = java.lang.System.getProperty("os.name").lower()
    return ver

def getSaveDir():
    savedir=expanduser("~")
    ver=getOsVersion()
    if (ver == "mac os x"):
        savedir+="/Documents/sketchPathTest"
    # Other os tests go here
    return savedir

I hope this helps.

Oh, this is just brilliant! Thank you for sharing it here!

This is just what I needed, thanks for your help!