Is it possible to capture off-screen objects using CoronaSDK display.capture()?

The display.capture API in CoronaSDK has the isFullResolution option and setting that option to true makes the captured image to not clip the display group’s content to the screen bounds. However sprites/objects that are entirely offscreen aren’t visible. This happens with both the table rows, the texts and images. 

Is there any way to force Corona to include all that in the snapshot? So if I wanted to make an image with a really long table view contents, could I do this?

Hi @jwatts,

Are you extending your TableView off the screen as well? By design, TableViews cull/clip rows that move outside their bounds, so it may be that display.capture() is getting the offscreen content (as it should with that boolean added) but that the rows simply don’t exist offscreen.

Take care,

Brent

Hey

I just tried the similar thing - but using text labels. Basically I was adding text labels to a group, one below the other, then took the screen capture using display.capture.

Here is my code. It iterates over a table (it has 8 elements in this case) and just adds the text labels to the group. Then it makes the screen capture of this group. 

 local grp = display.newGroup () local ov = display.newGroup () local lastX, lastY = 0, 0 for \_, m in pairs ( models ) do local md = display.newText ({ text = "This is line number " .. \_, fontSize = 28, font = "assets/28 Days Later.ttf", }) md:setFillColor ( 0 ) md.x, md.y = 20, lastY lastY = lastY + md.contentHeight + 60 lastX = math.max ( lastX, md.x + md.contentWidth ) md.anchorX, md.anchorY = 0, 0 grp:insert ( md ) end local bg = display.newImageRect ( "graphics/Background.png", lastX, lastY) bg.anchorX = 0 bg.anchorY = 0 grp.anchorX, grp.anchorY = 0, 0 bg.x, bg.y = 0, 0 ov:insert ( bg ) ov:insert ( grp ) grp.x, grp.y = 0, 0 ov.y = 0 display.save ( ov , { isFullResolution = true, filename = "xx.jpg" } )

I use isFullResolution and it works in a way that it doesn’t cut out the background image on the screen edge. However, whatever label is FULLY outside of the screen doesn’t get to the screen capture. The resulting image looks like this. You can see that there are no texts below the “line number 5”, but the background extends for the next 3 lines… 

xx.jpg

Hi all,

I am almost sure that using that boolean (as true) means that objects which are partially on screen will be captured in their entirety. However, Corona culls objects which are completely off-screen, so you won’t get those captured.

I admit we could clarify this better in the docs, so I’ll update them soon.

Best regards,

Brent

Well, I managed to (finally) make the screen capture, even with the offscreen elements. It seems like display.newSnapshot comes to the rescue.

 local lines = {} for \_, line in pairs ( texts ) do local t = display.newText ({ text = line, fontSize = 22, font = "assets/28 Days Later.ttf", }) t.x, t.y = 20 + t.contentWidth / 2, lastY + t.contentHeight / 2 lastY = lastY + t.contentHeight / 2 + 20 lastX = math.max ( lastX, t.x + t.contentWidth / 2 ) t:setFillColor ( 0, 0, 0 ) table.insert ( lines, t ) end lastY = lastY + 20 lastX = lastX + 20 local sn = display.newSnapshot ( lastX, lastY ) local bg = display.newImageRect ( "graphics/Background.png", lastX, lastY) bg.x, bg.y = 0, 0 sn.group:insert ( bg ) sn.group.anchorX = 0 sn.group.anchorY = 0 for i, o in pairs ( lines ) do o.anchorX, o.anchorY = 0.5, 0.5 o.y = o.y - lastY / 2 o.x = o.x - lastX / 2 sn.group:insert ( o ) end sn:invalidate() display.save ( sn , { isFullResolution = true, filename = "encounterExportImage.jpg" } ) sn:removeSelf ()

Hi all,

The engineers have looked into this again and we will probably be issuing a fix in an upcoming daily build, such that the off-screen children of a captured group will also be captured. Keep an eye on daily builds/notes upcoming, if this issue pertains to your projects.

Best regards,

Brent

+1 for this. Didn’t know we could capture off-screen graphic objects. Would be great for creating mask.

@yosu,

Even with the potential fix, it probably won’t work that way. I think some of the captured area will need to be on-screen for anything offscreen to be grabbed, so you won’t just be able to keep objects entirely offscreen and capture them at will.

Brent

Hi @jwatts,

Are you extending your TableView off the screen as well? By design, TableViews cull/clip rows that move outside their bounds, so it may be that display.capture() is getting the offscreen content (as it should with that boolean added) but that the rows simply don’t exist offscreen.

Take care,

Brent

Hey

I just tried the similar thing - but using text labels. Basically I was adding text labels to a group, one below the other, then took the screen capture using display.capture.

Here is my code. It iterates over a table (it has 8 elements in this case) and just adds the text labels to the group. Then it makes the screen capture of this group. 

 local grp = display.newGroup () local ov = display.newGroup () local lastX, lastY = 0, 0 for \_, m in pairs ( models ) do local md = display.newText ({ text = "This is line number " .. \_, fontSize = 28, font = "assets/28 Days Later.ttf", }) md:setFillColor ( 0 ) md.x, md.y = 20, lastY lastY = lastY + md.contentHeight + 60 lastX = math.max ( lastX, md.x + md.contentWidth ) md.anchorX, md.anchorY = 0, 0 grp:insert ( md ) end local bg = display.newImageRect ( "graphics/Background.png", lastX, lastY) bg.anchorX = 0 bg.anchorY = 0 grp.anchorX, grp.anchorY = 0, 0 bg.x, bg.y = 0, 0 ov:insert ( bg ) ov:insert ( grp ) grp.x, grp.y = 0, 0 ov.y = 0 display.save ( ov , { isFullResolution = true, filename = "xx.jpg" } )

I use isFullResolution and it works in a way that it doesn’t cut out the background image on the screen edge. However, whatever label is FULLY outside of the screen doesn’t get to the screen capture. The resulting image looks like this. You can see that there are no texts below the “line number 5”, but the background extends for the next 3 lines… 

xx.jpg

Hi all,

I am almost sure that using that boolean (as true) means that objects which are partially on screen will be captured in their entirety. However, Corona culls objects which are completely off-screen, so you won’t get those captured.

I admit we could clarify this better in the docs, so I’ll update them soon.

Best regards,

Brent

Well, I managed to (finally) make the screen capture, even with the offscreen elements. It seems like display.newSnapshot comes to the rescue.

 local lines = {} for \_, line in pairs ( texts ) do local t = display.newText ({ text = line, fontSize = 22, font = "assets/28 Days Later.ttf", }) t.x, t.y = 20 + t.contentWidth / 2, lastY + t.contentHeight / 2 lastY = lastY + t.contentHeight / 2 + 20 lastX = math.max ( lastX, t.x + t.contentWidth / 2 ) t:setFillColor ( 0, 0, 0 ) table.insert ( lines, t ) end lastY = lastY + 20 lastX = lastX + 20 local sn = display.newSnapshot ( lastX, lastY ) local bg = display.newImageRect ( "graphics/Background.png", lastX, lastY) bg.x, bg.y = 0, 0 sn.group:insert ( bg ) sn.group.anchorX = 0 sn.group.anchorY = 0 for i, o in pairs ( lines ) do o.anchorX, o.anchorY = 0.5, 0.5 o.y = o.y - lastY / 2 o.x = o.x - lastX / 2 sn.group:insert ( o ) end sn:invalidate() display.save ( sn , { isFullResolution = true, filename = "encounterExportImage.jpg" } ) sn:removeSelf ()

Hi all,

The engineers have looked into this again and we will probably be issuing a fix in an upcoming daily build, such that the off-screen children of a captured group will also be captured. Keep an eye on daily builds/notes upcoming, if this issue pertains to your projects.

Best regards,

Brent

+1 for this. Didn’t know we could capture off-screen graphic objects. Would be great for creating mask.

@yosu,

Even with the potential fix, it probably won’t work that way. I think some of the captured area will need to be on-screen for anything offscreen to be grabbed, so you won’t just be able to keep objects entirely offscreen and capture them at will.

Brent