Display.save crops display object if it's in an offset group

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.

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)

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.

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

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