Problem with SaveImage()

@simeon, I was having problems getting saveimage() to work in Xcode, but had no issue on codea runtime.
I think the problem is with the function itself.

I made a new project with just the simplest example given in the help file itself " i.e. my image = image(400,400)… saveImage(“Documents:test”,my image)", it returns the same error in xcode

“Invalid sprite pack name”

Hope this would be this would be fix at the next patch. Otherwise saveimage would not be any use.

I am having exactly the same issue. Would be great to see this resolved, or perhaps a workaround?

This is an issue to do with the assetpack name now being reserved for ondemand resources in Xcode 7. This has been fixed in the 2.3.2 runtime, by renaming the asset folders to assets.

I just did a test of saveImage in Xcode (just in the simulator) using the 2.3.2 runtime (I’m a betatester) and it worked (the image was saved to the documents folder in the simulator) without an error.

Codea 2.3.2 was submitted to the App Store 10 days ago (Apple always take a long time to review code execution apps, so hard to say when it will become available). If you don’t want to wait, you can follow the steps here to download the 2.3.2 runtime:

http://codea.io/talk/discussion/comment/63258/#Comment_63258

also here:

http://codea.io/talk/discussion/6922/how-to-update-to-the-new-runtime-follow-up-on-codea-xcode-s-asset-issue

2.3.2 came out a while ago, should be working now. Have you tried re-exporting to Xcode with the latest version of Codea?

This is great news! :slight_smile: Look forward to it

Has anyone got this to work in Xcode in the latest version? I’m still having the same issues.

When I tried last November:

I just did a test of saveImage in Xcode (just in the simulator) using the 2.3.2 runtime and it worked (the image was saved to the documents folder in the simulator) without an error.

Can you give more details? It’s an “invalid sprite pack name” error you’re getting? In the simulator or when deployed to device? Have you tried it with different save locations? Have you checked that a folder with the corresponding name is in the Xcode project?

Not the simulator. On the iOS device through a build deployed to device. The error is “invalid sprite pack name”. Either folders ( documents or dropbox). There are the folders in Xcode as I have existing files in documents/dropbox. So I can load existing files, but I cannnot create or overwrite files.

Even savetext is not working as it should. There is no error, but it is clearly not saving into the same folder path as readtext. I.e. You can savetext to “documents” path, but when reading the same “documents” path, you would not find the file. So you can load existing files but cannot create or overwrite files.

I have not tried using simpler examples. But I think it’s the same problem as above. I might be doing someone wrong. Has anyone got it to work yet?
Everything works well in codea runtime.

If you test it in the simulator as well though it can be easier to diagnose what is going on, as you can analyse the app bundle to work out exactly where stuff is being saved to.

If I recall there was something unusual going on where it looked as if there were two dropbox.assetpack folders, one in the app bundle (ie read only), and one in app’s data bundle (ie meant to be modified). There seems to be some kind of bifurcation going on when you moe to Xcode. I wonder whether this is connected to the issue you’re having. I found this because the Lua io/ file commands can’t read assets in Xcode, because the os.home variable in Xcode points to the data bundle.

In the other thread @FearMe2142 seemed to get saveImage working in Xcode?

So I wrote a simple test to see where the problem lies.

function setup()
     print("Test 1: Saving text using savetext")
    mysavetext = "this is done using savetext"
    local addstring = tostring(math.random(1,1000))
    print("Random number"..addstring)
    saveText("Documents:savetextfile",mysavetext)
    saveText("Dropbox:savetextfile",mysavetext)
    saveText("Project:savetextfile",mysavetext)
    saveText("Documents:savetextfile"..addstring,mysavetext)
    saveText("Dropbox:savetextfile"..addstring,mysavetext)
    saveText("Project:savetextfile"..addstring,mysavetext)
    
    ---------
    print("OS home points to:"..(os.getenv("HOME")))
    print("Test 2: Saving text using i/o functions")
    iotextfile = os.getenv("HOME").."/Documents/iotextfile.txt"
    local handle1 = (io.open(iotextfile,"w"))    
    if handle1 == nil then print("Test2a failed: could not write to document")
    else
        print("Managed to use io to make a new file in documents")
        handle1:write("This is done using io\
")
        handle1:close()
    end
    iotextfile2 = os.getenv("HOME").."/Dropbox/iotextfile.txt"
    local handle2 = (io.open(iotextfile2,"w"))
    if handle2 == nil then print("Test2b failed: could not write to dropbox")
    else
        print("Managed to use io to make a new file in dropbox")
        handle2:write("This is done using io\
")
        handle2:close()
    end    
    iotextfile3 = os.getenv("HOME").."/Project/iotextfile.txt"
    local handle3 = (io.open(iotextfile3,"w"))
    if handle3 == nil then print("Test2c failed: could not write to project")
    else
        print("Managed to use io to make a new file in project")
        handle3:write("This is done using io\
")
        handle3:close()
    end
    iotextfile = os.getenv("HOME").."/Documents/iotextfile"..addstring..".txt"
    local handle1 = (io.open(iotextfile,"w"))    
    if handle1 == nil then print("Test2d failed: could not write to new document")
    else
        print("Managed to use io to make a new file in documents")
        handle1:write("This is done using io\
")
        handle1:close()
    end
    iotextfile2 = os.getenv("HOME").."/Dropbox/iotextfile"..addstring..".txt"
    local handle2 = (io.open(iotextfile2,"w"))
    if handle2 == nil then print("Test2e failed: could not write to new dropbox")
    else
        print("Managed to use io to make a new file in dropbox")
        handle2:write("This is done using io\
")
        handle2:close()
    end    
    iotextfile3 = os.getenv("HOME").."/Project/iotextfile"..addstring..".txt"
    local handle3 = (io.open(iotextfile3,"w"))
    if handle3 == nil then print("Test2f failed: could not write to new project")
    else
        print("Managed to use io to make a new file in project")
        handle3:write("This is done using io\
")
        handle3:close()
    end
    ---
    print("Test3: Now try to read those files using readtext")
    local myreadtext = readText("Documents:savetextfile")
    if myreadtext == nil then print("test3a: Readtext from Documents failed")
    else print("Readtext from documents:"..myreadtext)
    end
    myreadtext = readText("Documents:savetextfile"..addstring)
    if myreadtext == nil then print("test3b:Readtext from Documents failed")
    else print("Readtext from documents2:"..myreadtext)
    end
    myreadtext = readText("Dropbox:savetextfile")
    if myreadtext == nil then print("test3c:Readtext from Dropbox failed")
    else print("Readtext from dropbox:"..myreadtext)
    end
    myreadtext = readText("Dropbox:savetextfile"..addstring)
    if myreadtext == nil then print("test3d:Readtext from Dropbox failed")
    else print("Readtext from dropbox:"..myreadtext)
    end
    myreadtext = readText("Project:savetextfile")
    if myreadtext == nil then print("test3e:Readtext from Project failed")
    else print("Readtext from project:"..myreadtext)
    end
    myreadtext = readText("Project:savetextfile"..addstring)
    if myreadtext == nil then print("test3f:Readtext from Project failed")
    else print("Readtext from project:"..myreadtext)
    end
    ------
    print("Test4: Now try to read those files.  <io read>")
    local readiotextfile = os.getenv("HOME").."/Documents/iotextfile.txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test4a: io read documents done")
    readiotextfile = os.getenv("HOME").."/Dropbox/iotextfile.txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test4b: io read dropbox done")
    readiotextfile = os.getenv("HOME").."/Project/iotextfile.txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test4c: io read project done")
    
    print("Test5: Read usergenerated filenames using io")
    local readiotextfile = os.getenv("HOME").."/Documents/iotextfile"..addstring..".txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test5a:io read documents2 done")
    readiotextfile = os.getenv("HOME").."/Dropbox/iotextfile"..addstring..".txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test5b:io read dropbox2 done")
    readiotextfile = os.getenv("HOME").."/Project/iotextfile"..addstring..".txt"
    io.input(io.open(readiotextfile,"r"))
    for i in io.lines() do print(i) end
    print("test5c:io read project2 done")
    ----
    print("test6: Testing saveimage")
    mysaveimage = image(400,400)
    setContext(mysaveimage)
    background(0,0,0,0)
    fill(255,0,0)
    text("This is done using saveimage",100,100)
    setContext()
    print("Saving image using saveimage")
    saveImage("Documents:saveimagefile",mysaveimage) -- xcode: invalid spritepack
    saveImage("Dropbox:saveimagefile",mysaveimage)
    saveImage("Project:saveimagefile",mysaveimage)
     saveImage("Documents:saveimagefile"..addstring,mysaveimage)
    saveImage("Dropbox:saveimagefile"..addstring,mysaveimage)
    saveImage("Project:saveimagefile"..addstring,mysaveimage)
    ---
    print("now readimage")
    local myreadimage = readImage("Documents:saveimagefile")
    local w,h = spriteSize(myreadimage)
    print("Readimage from document. w:"..w.." h:"..h)
    myreadimage = readImage("Dropbox:saveimagefile")
    local w,h = spriteSize(myreadimage)
    print("Readimage from dropbox. w:"..w.." h:"..h)
    myreadimage = readImage("Project:saveimagefile")
    local w,h = spriteSize(myreadimage)
    print("Readimage from project. w:"..w.." h:"..h)
    myreadimage = readImage("Documents:saveimagefile"..addstring)
    local w,h = spriteSize(myreadimage)
    print("Readimage from document2. w:"..w.." h:"..h)
    myreadimage = readImage("Dropbox:saveimagefile"..addstring)
    local w,h = spriteSize(myreadimage)
    print("Readimage from dropbox2. w:"..w.." h:"..h)
    myreadimage = readImage("Project:saveimagefile"..addstring)
    local w,h = spriteSize(myreadimage)
    print("Readimage from project2. w:"..w.." h:"..h)

Results
In code runtime, test 2b, 2c,2e, 2f failed. I.e you cannot use i/o functions to write on existing or new files on dropbox or project, but can do so on documents folder.

Hence can’t read from dropbox/project using I/o. Test 4b,4c, 5b,5c.

Readtext and saveimage works perfectly regardless of folder and user-generated files.

Xcode deployed build results;
Same problem as above. In addition, failed 3b, 3d,3f. I.e. Savetext cannot create new user generated files in any folders. In addition, 5a does not seem to be working (I need to reconfirm this), so I/o functions cannot write user generated files in documents either

In addition, Saveimage does not work on any folders because of the invalid asset problem.

These are peculiar bugs. Seems like there is no work around if you want to write data. I do hope the next codea build can finally solve this problem with saveimage and Savetext/readtext. In the meantime, if anyone knows of a work around to write large chunks of data, pls do let me know.

correction. test 5a works. Till this gets resolved in the next Codea version, to use savetext/readtext in an app, you will need to a)load up your existing text data using readtext, b) write them back using i/o for the first run of your app and c) henceforth use i/o.

A related problem, I think, is if I want to use the camera for an existing sprite. Say I take a picture with camera and use saveimage to save into an existing asset. It would not show up until I restart the app. Same goes for downloading a sprite from dropbox during runtime. It doesn’t update till I restart the app.

@zapaper Maybe this will help.

displayMode(FULLSCREEN)

function setup()
    cameraSource(CAMERA_BACK)
end

function draw()
    background(40, 40, 50)
    fill(255)
    text("tap screen to take picture",WIDTH/2,HEIGHT-50)
    if img~=nil then
        sprite(img,WIDTH/2,HEIGHT/2)
    else
        sprite(CAMERA,WIDTH/2,HEIGHT/2) 
    end  
end

function touched(t)
    if t.state==BEGAN then
        img=image(CAMERA)
    end
end

@dave1707, thanks. I’m actually commenting on saveimage(), which currently does not work in xcode. This in turn affects image you want to use from the camera beyond the first instance (e.g. saving a player profile).

I was working on an Encoder function, were every image Pixel would be made into the entire Image String, but that String was so Long…

Didn’t close the loop on this thread. I found a way to get around the bug within codea.

The problem was with “documents:file”. If you want to write new data while in the app and use it in the app, do not use “documents:file” anywhere in your code. This is because the “my documents” folder that gets exported into Xcode will be different from the “my documents” Xcode later use to write using readtext/savetext or save image. By not using “documents:file” in your code, the “my documents” folder does not get created in your export.

Then in the app, you can generate files and read/write them using “Documents:”… filename. This will work.