display.save boundaries issue in letterbox format

Hello guys,

I’m having an issue trying to save a screenshot of my game using the ‘letterbox’ scaling option.

It seems that the resulting image only save the display content size (instead of display actual content size).

Basically cropping top/bottom parts on tall devices (galaxy S5) and left/right parts on large devices (ipad).

I’m using:

[lua]

display.save( display.getCurrentStage(), { filename=“test.png”, baseDir=system.DocumentsDirectory,

                      captureOffscreenArea=true, backgroundColor={0} } )

[/lua]

Does anybody else has this problem too ?

I tried setting ‘captureOffscreenArea’ to false or true but doesn’t seem to change anything.

I don’t know if that is the intended way ‘display.save’ is supposed to work.

If so, how can I save the whole screen ?

Thanks in advance for your lights on this subject,

GoG

Can you put together a simple demo project that shows off this problem and share it with us? A link to a .zip file on Dropbox or Google Drive would be great.

Rob

Hello Rob,

I’ll put together a quick demo asap and share it with you.

Thanks!

GoG

Hi Rob,

Here it is:

https://www.dropbox.com/s/4otvfcouvc1esom/testCapture.zip?dl=0

Just press the app “Capture” button in simulator, using an iPad or Samsung galaxy skin (large/tall devices).

Then check the resulting screenshot image in the associated ‘system.DocumentsDirectory’.

The image miss top/bottom or left/right parts depending on device type.

Hope this will help!

GoG

I think I have this solved.  You are using display.getCurrentStage() to fetch the display object to capture. It may be possible that object is bounded by the content area defined in your config.lua.

I created an empty display group at the top of your code:

local screenGroup = display.newGroup()

then I added your display objects to that group instead of just letting them be added to the stage, for instance:

local bgImg = display.newImageRect( screenGroup, "bg.jpg", display.actualContentWidth, display.actualContentHeight )

Then I changed your display.save call to:

 display.save( screenGroup, { filename="capture.png", baseDir=system.DocumentsDirectory, captureOffscreenArea=false, backgroundColor={0} } )

And I started getting the full screen image.

Rob

Hello Rob,

Thanks for the quick answer and the workaround!

Do you know how I could implement it using composer scenes ?

I usually capture my screenshot when an overlay scene is displayed (on top of my game scene),

so I’m not sure how I can put everything in a single group between them.

PS: do you think this is normal behavior for ‘display.save’ to only save content area ?

Or could it be changed in future version (or at least appear as a function parameter) to capture actual content ?

Thanks again,

GoG

Have you looked at display.captureScreen()?
 

https://docs.coronalabs.com/api/library/display/captureScreen.html

Rob

Hi Rob,

Yes, I looked at the ‘captureScreen’ function but it only save the image in the device’s photo library,

asking user for special permissions to do so (which will be weird to just share a screenshot as I use it for).

Plus it places the resulting image on top of the screen (even if manually removed, not really ideal).

Is there another way to just let ‘display.save’ capture the whole screen ?

Should I fill a bug report or feature request ?

Thanks,

GoG

I’d file it as a bug report.  

Rob

Thanks Rob,

I just reported it as a bug.

Hope it will be fix soon…

GoG

Hello!

Try following:

[lua]

local function onCapture()

    local captureObject = display.captureBounds {

        xMin = display.safeScreenOriginX,

        yMin = display.safeScreenOriginY,

        xMax = display.actualContentWidth,

        yMax = display.actualContentHeight,

    }

    local saveGroup = display.newGroup( )

    saveGroup:insert( captureObject )

    display.save( saveGroup, { filename=“capture.png”, baseDir=system.DocumentsDirectory,

                  captureOffscreenArea=true, backgroundColor={0} } )

    saveGroup:removeSelf( )

    cptTxt.text = “Done”

end

[/lua]

add the origins to xMax/yMax (else w/h alone won’t form proper bounds when non-zero origin)

Hello,

Thank you for your support.
The workaround seems to work nicely.

@davebollinger: you’re right, it won’t save non-safe areas (e.g. area under status bar) with these parameters.

The suggested changes to ‘display.save’ API might still be interesting for future releases, I think.

Regards,
GoG

if you want to capture everything on screen then simply do this

 local capture = display.captureScreen(true) display.remove(capture) capture = nil

Can you put together a simple demo project that shows off this problem and share it with us? A link to a .zip file on Dropbox or Google Drive would be great.

Rob

Hello Rob,

I’ll put together a quick demo asap and share it with you.

Thanks!

GoG

Hi Rob,

Here it is:

https://www.dropbox.com/s/4otvfcouvc1esom/testCapture.zip?dl=0

Just press the app “Capture” button in simulator, using an iPad or Samsung galaxy skin (large/tall devices).

Then check the resulting screenshot image in the associated ‘system.DocumentsDirectory’.

The image miss top/bottom or left/right parts depending on device type.

Hope this will help!

GoG

I think I have this solved.  You are using display.getCurrentStage() to fetch the display object to capture. It may be possible that object is bounded by the content area defined in your config.lua.

I created an empty display group at the top of your code:

local screenGroup = display.newGroup()

then I added your display objects to that group instead of just letting them be added to the stage, for instance:

local bgImg = display.newImageRect( screenGroup, "bg.jpg", display.actualContentWidth, display.actualContentHeight )

Then I changed your display.save call to:

 display.save( screenGroup, { filename="capture.png", baseDir=system.DocumentsDirectory, captureOffscreenArea=false, backgroundColor={0} } )

And I started getting the full screen image.

Rob

Hello Rob,

Thanks for the quick answer and the workaround!

Do you know how I could implement it using composer scenes ?

I usually capture my screenshot when an overlay scene is displayed (on top of my game scene),

so I’m not sure how I can put everything in a single group between them.

PS: do you think this is normal behavior for ‘display.save’ to only save content area ?

Or could it be changed in future version (or at least appear as a function parameter) to capture actual content ?

Thanks again,

GoG

Have you looked at display.captureScreen()?
 

https://docs.coronalabs.com/api/library/display/captureScreen.html

Rob