Camera capture too slow

i was playing with the idea of making a time lapse app, just for fun, and ran into a problem: capturing the image from the camera significantly slows down the code

in the code below, comment the line to get the Camera image to see the difference (without that line it properly captures 30 frames per second)

function setup()
    cameraSource(CAMERA_FRONT)
    
    capturesPerSecond = 30
    interval = 1 / capturesPerSecond
    
    frames = {}
    
    nexttime = interval

    tween.delay(1, function() print(#frames) end)
end

function draw()
    background(40, 40, 50)
    
    if nexttime - ElapsedTime <= 0 then
        nexttime = nexttime + interval
       
        local img = image(CAMERA) -- Comment this line to see the difference
        table.insert(frames, img or 1)
    end
end

Has anyone worked with the camera and Codea before or have any tips on how to get around this?

I think 30 captures a second is way too many!

@JakAttak I had this, not sure if you can get anything from it that you can use.

http://codea.io/talk/discussion/5707/time-lapse-pictures#Item_13

@Ignatz, is it? I figured 1x would be 30, 2x would be 15, etc, and play them back at 30fps

@dave1707, thanks I’ll take a look

EDIT: looking at this link (http://www.studioneat.com/blogs/main/15467765-how-does-the-ios-8-time-lapse-feature-work) from the above discussion, I see 30 captures a second is probably indeed much to many…

@JakAttak - Awe. I was about to send you that link. Anyways, I found TUAW’s explanation much better. Be sure to share this code, if you implement Apple’s method. I’d be interested to see how well a 3rd party implementation works.
Thanks!

@Zoyt, it seems to work pretty well, but I’ve run into another issue with Codea crashing, likely due to storing all those images

@JakAttak Here’s a version that captures 1.6 pictures per second and plays back at 11 pictures per second. I’m not sure if I can get more than 11 per second even though I’m coded for 25 per seconds. Also, I’m coded for taking 2 pictures per second but only getting 1.6. I have maxPictures set at 120 to keep from filling up memory. I’m running this on an iPad Air, so I’m not sure how fast it will run on the other iPads.


function setup()
    maxPictures=120
    parameter.action("Start pics",startPics)
    parameter.action("Stop pics",stopPics)
    parameter.action("Start show",startShow)
    parameter.action("Stop show",stopShow)
    parameter.action("Delete",deletePics)
    cameraSource(CAMERA_BACK) 
    startPics=false
    startShow=false
end

function draw()
    background(40, 40, 50)
    if not startShow then
        str=image(CAMERA)
        if str then
            sprite(str,WIDTH/2,HEIGHT/2)
        end
    end
    if startPics then
        timer=timer+DeltaTime
        if timer>=.5 then
            timer=0
            picture=picture+1
            pic=string.format("Dropbox:pics#%04d",picture)
            output.clear()
            print(pic)
            saveImage(pic,str)
            if picture>=maxPictures then
                stopPics()
            end
        end 
    end 
    if startShow then
        if str1 then
            sprite(str1,WIDTH/2,HEIGHT/2)
        end
        timer=timer+DeltaTime
        if timer>=.04 then
            timer=0
            picture=picture+1
            pic=string.format("Dropbox:pics#%04d",picture)
            output.clear()
            print(pic)
            str=readImage(pic)
            if str then
                str1=str
            else
                picture=0
            end
        end 
    end 
end

function startPics()
    output.clear()
    print("Start pics")
    deletePics()
    sc=os.clock()
    startPics=true
    startShow=false
    picture=0
    timer=0
end

function stopPics()
    print("Stop pics")
    startPics=false
    print(os.clock()-sc)
end

function startShow()
    output.clear()
    print("Start show")
    picture=0
    timer=0
    startShow=true
    startPics=false
end

function stopShow()
    print("Stop show")
    startShow=false    
end

function deletePics()
    output.clear()
    print("Delete pictures")
    count=0
    local sl=spriteList("Dropbox")
    for a,b in pairs(sl) do
        if string.sub(b,1,5)=="pics#" then
            saveImage("Dropbox:"..b,nil)
            count=count+1
        end
    end
    print(count.."  pictures deleted")
end

@JakAttak - Are you storing them in an array or saving them? Your RAM would fill up pretty fast if you save them in an array.

@Zoyt, @dave1707, yup, seems to be a lose-lose situation - use saveImage to avoid RAM fill up and it cant run fast, store them in a table to go fast and it runs out of space and crashes

Have you considered resizing the images? It may be slower, but it’d help. If you do do that, I suggest you run it in a separate thread as to not interrupt the main thread. (How to here)

@Zoyt I’ve tried something similar before and can confirm that Codea will crash after too many images (not enough RAM), but here’s another problem: the file IO isn’t fast enough to read the images back at 60 FPS.

@SkyTheCoder @JakAttak - That’s why there’s a processing state to convert it to a video. So what you probably want to do is then send the photos to a server and use MMPEG to convert them to a movie. When it’s finished, you can then pop open a web browser and show the video. Kind of hacky, but it’s what you’ve got.