Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Display.save crops display object if it's in an offset group
Started by i.rovang Oct 16 2019 08:48 PM

4 replies to this topic

Best Answer davebollinger , 17 October 2019 - 07:46 AM

display.save() has always seemed a bit wonky to me.  i suspect the behavior is consistent, but it's certainly not intuitive, and the docs don't go deep enough to explain it.  parent transforms (ie, from outer groups) don't appear to be respected, though inner transform (ie, of contained groups, like your "group") will be.  so what i've done in the past is wrap everything intended for capture in an untransformed (ie:  x,y,rotation=0,0,0) group just for the duration of capture, then do the capture with captureOffscreenArea=true, then put the target back into whatever group it originally came from.  roughly (pseudocode) like:

group = display.newGroup()
group.y = non-zero value
-- add stuff to group, whatever..
-- later:
capturegroup = display.newGroup()
capturegroup:insert(group)
display.save(capturegroup, { captureOffscreenArea=true, etc.. })
originalParentOfGroup:insert(group)
display.remove(capturegroup)

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

i.rovang

[GLOBAL: userInfoPane.html]
i.rovang
  • Observer

  • 4 posts
  • Corona SDK

I've been having problems with display.save on objects in groups, and I eventually realized the problem pertains to objects whose parent group has been moved with an x or y offset.

 

Example:

 

local group = display.newGroup()
group.y = 25

local img = display.newImageRect ( group, "Icon.png", 100, 100 )
img.x, img.y = 100, 100

local temp = system.TemporaryDirectory
local fn = "temp.png"

display.save ( img, { filename = fn, baseDir = temp } )

local img2 = display.newImageRect ( group, fn, temp, 100, 100 )
img2:setFillColor ( 1, 0, 0 )
img2.x, img2.y = 200, 100

Here I place the "img" graphic inside a group which has been moved down by 25px. I'm then trying to bring it back in as "img2" and tint it red, setting it beside the original. But you can see it's cropped by 25px, and the crop amount varies according to whatever offset the group has. (Tested in builds 3520 and 3540.)

 

Ordinarily instead of a simple image, I'm trying to render a group within a group to a raster image, and to that end I suspect I should be using snapshots instead, but I was just wondering if this is what display.save is supposed to be doing in this case. I notice display.save does crop objects which are partially off-screen when saved, which I can understand, but cropping an object due to its group's offset just seems bizarre to me.

Attached Files



[TOPIC: post.html]
#2

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

  Best Answer

display.save() has always seemed a bit wonky to me.  i suspect the behavior is consistent, but it's certainly not intuitive, and the docs don't go deep enough to explain it.  parent transforms (ie, from outer groups) don't appear to be respected, though inner transform (ie, of contained groups, like your "group") will be.  so what i've done in the past is wrap everything intended for capture in an untransformed (ie:  x,y,rotation=0,0,0) group just for the duration of capture, then do the capture with captureOffscreenArea=true, then put the target back into whatever group it originally came from.  roughly (pseudocode) like:

group = display.newGroup()
group.y = non-zero value
-- add stuff to group, whatever..
-- later:
capturegroup = display.newGroup()
capturegroup:insert(group)
display.save(capturegroup, { captureOffscreenArea=true, etc.. })
originalParentOfGroup:insert(group)
display.remove(capturegroup)

  • i.rovang likes this

[TOPIC: post.html]
#3

i.rovang

[GLOBAL: userInfoPane.html]
i.rovang
  • Observer

  • 4 posts
  • Corona SDK

Thanks for the reply, Dave. I was thinking that might have to be my workaround as well. Glad to hear I'm not alone in finding it a bit nonintuitive.

 

Have you used snapshots enough to know whether they're any more intuitive regarding cropping and transforms? I just ran across the snapshot feature and haven't had time to explore it fully yet.



[TOPIC: post.html]
#4

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

nope, can't say.  you might also try as workaround:  display.captureBounds (the only one that seems intuitive to me in this regard) later followed by display.save (with the capture as target), then remove capture from display.  hth


  • i.rovang likes this

[TOPIC: post.html]
#5

i.rovang

[GLOBAL: userInfoPane.html]
i.rovang
  • Observer

  • 4 posts
  • Corona SDK

Okay, I gave snapshots a try, and they don't seem to crop an offset group, so that's nice, but I haven't figured out how to "stamp" a group into a canvas without the group remaining part of the snapshot.

 

My sample, which is wrong because the last two lines take the group back out of the snapshot, whereas without the last two lines it stays in the snapshot (I want to see it both in the snapshot and out of it simultaneously):

local group = display.newGroup()
group.x, group.y = 100, 100
local img = display.newImage ( group, "Icon.png" )
local img2 = display.newImage ( group, "Icon.png" )
img2.x, img2.y = 20, 20

local snapshot = display.newSnapshot ( 400, 400 )
snapshot.x, snapshot.y = 0, 0

snapshot.canvas:insert ( group )
snapshot:invalidate ( "canvas" )
snapshot:setFillColor ( 1, 0, 0 )

display.getCurrentStage():insert ( group )
group.x = 200

So if anyone can point out a minor fix for how I'm trying to use snapshots (incorrectly?), I'd appreciate it, but otherwise I modified my original example per Dave's suggestion to avoid the cropping by moving it to the current stage before saving.

local group = display.newGroup()
group.y = 25

local img = display.newImageRect ( group, "Icon.png", 100, 100 )
img.x, img.y = 100, 100

local temp = system.TemporaryDirectory
local fn = "temp.png"

local oldParent = img.parent -- added line
display.getCurrentStage():insert ( img ) -- added line
display.save ( img, { filename = fn, baseDir = temp } )
oldParent:insert ( img ) -- added line

local img2 = display.newImageRect ( group, fn, temp, 100, 100 )
img2:setFillColor ( 1, 0, 0 )
img2.x, img2.y = 200, 100

Attached Files




[topic_controls]
[/topic_controls]