[Feature Request] Image ScreenCapture Function

I will go straight to the point.

This can be done here:

But I want to capture what I see on screen using a function and then save the image in Documents and then display it.

Function should look like this:

image = ScreenCapture(x,y,w,h or null for fullscreen)
saveImage("Documents:ScreenCapture", image)

Well, firstly Simeon has a couple tutorials available that cover this. They should be visible in your project viewer by way of update. If you have not updated your Codea on your ipad i suggest you do so now.

Hello @Georgian. You may be interested in the page on the wiki here.

Alternatively heres my stab at putting together something along those lines:

-- imagcon Toggle 2
--clearProjectData()
-- Use this function to perform your initial setup
function setup()
    
 setInstructionLimit(0)
    
 
    
    --[[
    if you want to manually select 
    and delete some images go here
    readImage()
    
    
    Otherwise you can select an image from your Documents folder
    by Default while running this program through the Your_Current_Image
    
    --]]
    Instructions_and_Results()
    
    alpha = 255 --sets the capture area's alpha channel 
                --so you can see it before capture 
                --it turns invisible when you make a capture

bga = alpha --sets the BackGround Alpha 
            --so you can see the background color
            --you will be given the option 
            --to remove it or not
            


    Capwidth = 200
    Capheight = Capwidth
    
    
    Imgwidth = 200
     
    spritex = Capwidth/2
    spritey = spritex
    Your_Current_Image = 1 
    
     
    
    
    dynameters()
end

function Instructions_and_Results()
    capnum = nil
    screencaps = 0
    imagcaps = 0
    imgnum = nil
 
    fontbga = 255
buttonbga = 255
    
    
    print("ImagCon-T"..RETURN)
    
    for screens,cap in pairs(spriteList("Documents")) do
        
            if imgnum == nil then 
        imgnum = 1 
         if Images == nil then Images = {"Documents:"..cap} end
        Images[imgnum] = "Documents:"..cap
            else
        imgnum = imgnum + 1
        
    if Images[imgnum] == nil then Images[imgnum] = "Documents:"..cap end

    end
        
        
        
        
      if capnum == nil and string.sub(cap,7,9) == "Cap" then 
        
      capnum = 1
   


print(cap)
    elseif string.sub(cap,7,9) == "Cap" then
       capnum = capnum + 1
    
     
    
    print(cap)
     
    end --if
    
    if string.sub(cap,1,9) == "ImagCnCap" then 
    if imagcaps == 0 then 
    imagcaps = 1 
    
    else
imagcaps = imagcaps + 1 

    end --if
   end --if 
    
    
if string.sub(cap,1,9) == "ScreenCap" then 
    if screencaps == 0 then 
    screencaps = 1 
    else
screencaps = screencaps + 1 
end --
end
    
    
    end 
    
    if capnum == nil then 
       Capturetotal = "There are no Captures at this time"..RETURN 
    elseif capnum == 1 then 
    Capturetotal =" Capture total" 
    elseif capnum > 1 then  
    Capturetotal = " Captures total"
    end --if
    
    if  capnum ~= nil then
    print(RETURN..tostring(capnum)..Capturetotal)
    else
        print(RETURN..Capturetotal)
    end --if
  
      if screencaps > 0 then
if screencaps == 1 then 
totalscreencaps = " Screen Capture total" 
elseif screencaps > 1 then 
totalscreencaps = " Screen Captures total"
 end --if
    
     print(tostring(screencaps)..totalscreencaps)
    end
print("You have "..tostring(imgnum).." images Available in your Documents folder")

    
    print(RETURN.."Instructions:"..RETURN.."Make sure your image"..RETURN.."is inside the box to capture it "..RETURN.."(the image not the box)"..RETURN..RETURN.."For ScreenCaps:"..RETURN.."Make sure your CapHeight is set to 1024"..RETURN.."and your CapWidth is set to 768 for Fullscreen and full standard caps. "..RETURN..RETURN.."Anything less than those dimensions will not capture the entire screen."..RETURN..RETURN.."So it won't be saved as a Screencap. Instead it will be saved as ImagCnCap"..RETURN..RETURN.."Last but not least tap twice to the right of the parameters anywhere on the screen to the right to capture. Enjoy!")
    
    
end

 
function dynameters()  
 
    iparameter("Capwidth",16,768,Capwidth)
    iparameter("Capheight",16,HEIGHT,Capheight)
    iparameter("Imgwidth",16,WIDTH,Imgwidth)
    iparameter("spritex",0,WIDTH,spritex)
    iparameter("spritey",0,HEIGHT,spritey) 
    
    -- iparameter("wrapwidth",0,WIDTH,100)
       
    iparameter("Your_Current_Image",1,#Images,Your_Current_Image)

    
    
    if fieldbackup == nil then 
       
fieldbackup = {Capwidth}
fieldbackup[2] = Capheight
fieldbackup[3] = Imgwidth
fieldbackup[4] = spritex
fieldbackup[5] = spritey
fieldbackup[6] = Your_Current_Image
loadedsprite = readImage(Images[Your_Current_Image])
end
   
end
function draw()
     
    
     
   
    -- This sets a dark background color 
    
    
    if bga == 255 then
    background(40, 40, 50,bga)
    else
    background(0,0,0,bga)
    end




    -- This sets the line thickness
    strokeWidth(1)
    stroke(255,alpha)
    noFill()
rect(0,0,Capwidth,Capheight)

noStroke()
fill(0,0,255,buttonbga)
rect(125,497,25,12.5)

fill(255,0,0,buttonbga)
rect(179,499,17,9)






 

 



 --500

fill(0, 0, 0, buttonbga)
rect(125,542.9,87,15)

rect(232.886,542.9,72,15)


    -- Do your drawing here
    font("Courier")
fontSize(13)

    buttonbga = fontbga
    fill(255,fontbga)
textWrapWidth(242)
text("Capture the background as well? ",172,527)



text("Yes",139,502)     --497)   
text("No",188,503)   --510


 

font("Courier")
fontSize(13)
fill(255,fontbga)
textWrapWidth(181)
text("Fullscreen or Standard?",219,551)


if show == "full" then
displayMode(FULLSCREEN)

show = ""
elseif show == "stand" then
displayMode(STANDARD)

show = ""
end


if Your_Current_Image ~= fieldbackup[6] then 
fieldbackup[1] = Capwidth
fieldbackup[2] = Capheight
fieldbackup[3] = Imgwidth
fieldbackup[4] = spritex
fieldbackup[5] = spritey
fieldbackup[6] = Your_Current_Image
clearParameters()
Capwidth = fieldbackup[1] 
Capheight = fieldbackup[2] 
width = fieldbackup[3]

spritex = fieldbackup[4] 
spritey = fieldbackup[5] 
Your_Current_Image = fieldbackup[6]
loadedsprite = readImage(Images[Your_Current_Image])

clearOutput()
dynameters()
Instructions_and_Results() 
print("loaded")
end





if spritex > Capwidth or spritex < 0 then 
fieldbackup[1] = Capwidth
fieldbackup[2] = Capheight
fieldbackup[3] = Imgwidth
fieldbackup[4] = spritex
fieldbackup[5] = spritey
fieldbackup[6] = Your_Current_Image
clearParameters()
Capwidth = fieldbackup[1] 
Capheight = fieldbackup[2] 
width = fieldbackup[3]

spritex = Capwidth/2

fieldbackup[4] = spritex
spritey = fieldbackup[5] 
Your_Current_Image = fieldbackup[6]
dynameters()
end

if spritey > Capheight or spritey < 0 then 
fieldbackup[1] = Capwidth
fieldbackup[2] = Capheight
fieldbackup[3] = Imgwidth

fieldbackup[4] = spritex
fieldbackup[5] = spritey
fieldbackup[6] = Your_Current_Image
clearParameters()
Capwidth = fieldbackup[1] 
Capheight = fieldbackup[2] 
width = fieldbackup[3]

spritex = fieldbackup[4] 
spritey = Capheight/2

fieldbackup[5] = spritey
Your_Current_Image = fieldbackup[6]
dynameters()
end 
    
    
   
sprite(loadedsprite,spritex,spritey,Imgwidth)

   if andanother == "y" then
        alpha = 0
        
 if omitbg == "n" then 
bga = 0 
elseif omitbg == "y" then 
    bga = 255
end

        fontbga = alpha
        buttonbga = fontbga
        
        clearOutput()
      
        andanother = ""
        SaveCap()
        
    end


end


function touched(touch)
    
       --touch based omission 
if touch.x > 0 and touch.x < Capwidth + 1 and touch.y < Capheight + 1 and touch.y > 0 and savedCap ~= nil then
savedCap:set(touch.x,touch.y,0,0,0,0)
end
    
    
    
  if touch.x >= 125  and touch.x <=125 + 87 and touch.y >= 542.9 and touch.y <= 542.9 + 15 then
show = "full"
elseif touch.x >= 232.886 and touch.x <= 232.886 + 72 and touch.y >= 542.9  and touch.y <= 542.9 + 15 then
show = "stand"
end  
    
    
if touch.x > -1 and touch.tapCount == 2 then 
    if touch.state == BEGAN or touch.state == MOVING then
    fontbga = 255
--elseif touch.state == ENDED then
        --fontbga = 0
        buttonbga = fontbga
    end
    
if touch.x >= 125  and touch.x <= 125 + 25 and touch.y >= 497 and touch.y <= 497 + 12.5 then
omitbg = "y"
andanother = "y" 
elseif touch.x >= 179  and touch.x <= 179 + 17 and touch.y >= 499 and touch.y <= 499 + 9 then
omitbg = "n"
andanother = "y" 
end
end
    
end
    --[[
    fill(0,0,255,buttonbga)
rect(125,497,25,12.5)

fill(255,0,0,buttonbga)
rect(179,500,17,8.5)
    --]]
 
function SaveCap()
  

if Capwidth == 768 and Capheight == 1024 then
if scrncp == nil then scrncp = 1 + screencaps else scrncp = scrncp + 1 end
savor =  "Documents:ScreenCap"..tostring(scrncp)
elseif Capwidth == Capheight or Capwidth < 768 or Capheight < 1024 then
if imgcp == nil then imgcp = 1 + imagcaps else imgcp = imgcp + 1 end
savor =  "Documents:ImagCnCap"..tostring(imgcp) 
end
 --ImagCnCap

savedCap =  image(Capwidth,Capheight)
setContext(savedCap)
draw()

setContext() 

saveImage(savor,savedCap)



alpha = 255
bga = alpha
show = "stand"
 Instructions_and_Results()
print("saved") 
end
Description = "ImagCon Guys this is it a way to capture, resize, and save what's on your screen. As well as a way to move, resize, capture, and save images you have in your spritepacks be it in your Documents folders or your camera roll . "..RETURN.."Special thanks to Simeon for the ScreenCap tutorial, without which none of this would be possible. As well as his image IO tutorial."

saveProjectInfo("Description",Description)
saveProjectInfo("Author","melrdmydea")

oh and incase you’re wondering it works. I’ve used it myself.
As for displaying it in one of your programs?
you’ll want to code in a sprite() function with a reference to the name of the image.

just code in sprite() then touch inside those () and you should bring up your spritepack. Go to documents and look for either ImagCnCap or ScreenCap. touch it and it will be assigned to that sprite

@mpilgrem, I tried this idea, but the screen goes black.

It would be great if the items would remain on the screen during capture.

Here’s the code:

function setup()
    displayMode(FULLSCREEN)
end

function draw()
    myImage = image(WIDTH, HEIGHT)
    setContext(myImage)
    
    background(40, 40, 50)
    
    if CurrentTouch.state == BEGAN then
        fill(16, 178, 197, 255)
    elseif CurrentTouch.state == MOVING then
        fill(255, 0, 0, 255)
    elseif CurrentTouch.state == ENDED then
        fill(210, 218, 16, 255)
    end

    ellipse(CurrentTouch.x, CurrentTouch.y, 100,100)
    
    setContext()
    if CurrentTouch.state == BEGAN then
        saveImage("Documents:ScreenCapture", myImage)
    end
end

I tried to duplicate code to display on the screen what is happening, but Codea was locked and closed.
Here’s the code:

function setup()
    displayMode(FULLSCREEN)
end

function draw()
    myImage = image(WIDTH, HEIGHT)
    setContext(myImage)
    
    background(40, 40, 50)
    
    if CurrentTouch.state == BEGAN then
        fill(16, 178, 197, 255)
    elseif CurrentTouch.state == MOVING then
        fill(255, 0, 0, 255)
    elseif CurrentTouch.state == ENDED then
        fill(210, 218, 16, 255)
    end

    ellipse(CurrentTouch.x, CurrentTouch.y, 100,100)
    
    setContext()
    if CurrentTouch.state == BEGAN then
        saveImage("Documents:ScreenCapture", myImage)
    end
    
    background(40, 40, 50)
    
    if CurrentTouch.state == BEGAN then
        fill(16, 178, 197, 255)
    elseif CurrentTouch.state == MOVING then
        fill(255, 0, 0, 255)
    elseif CurrentTouch.state == ENDED then
        fill(210, 218, 16, 255)
    end

    ellipse(CurrentTouch.x, CurrentTouch.y, 100,100)
end

Maybe I didn’t explain exactly.

I want to capture what is happening on the screen on the fly.

@Georgian did you even look at my code? The screen should not be going black if its my code youre referring to.

Also my code does work on the fly.

Also Georgian after about 4 sec your’s crashes. You need a conditional statement to stop the capture.

@melrdmydea , I’ll try your code, but it’s a BIG code 8-| I like small codes / solutions.

Thanks melrdmydea for help!

Finally, I think that would be great if there were a similar function for capture screen image like startRecording()

I like @mpilgrem solution. Its very short and simple. But is there any possibility to save the picture in the standard picture folder of the iPad? I would like to use that for my Fractal program. My last solution would be to call ObjectiveC code when creating the final ipa. I just need to get the LUA image moved to ObjectiveC… I think :slight_smile:

@Georgian: In your sample you only render to the image and not on the screen. If you only want to save while touched, then use it like @mpilfgrem to set context and then call draw from outside. If you really want to save the frame and see it on the screen, then just render the image. In your example above, just add this to your code after setContext():

...
spriteMode(CORNER)
sprite(myImage, 0, 0)

But it will be much slower to always render in an image and then render the image… i needed that, but it didnt work fast enough.