I WILL LOVE YOU FOREVER...

Hi Kenn,

Try re-scaling your screen capture image like the below.

local tmpImage= display.newImage(fileName, system.DocumentsDirectory)  
local xScale = 0.5 \* (myGroup.width / tmpImage.width)  
local yScale = 0.5 \* (myGroup.height / tmpImage.height)  
tmpImage:scale(xScale, yScale)  
tmpImage.x = display.contentWidth / 2  
tmpImage.y = display.contentHeight / 2  

The above code will display the captured image at the center of the screen at half width and height. Dividing the original object’s width by the image pixel width creates a scalar that converts pixels to content coordinates, which will work on all resolutions. [import]uid: 32256 topic_id: 12957 reply_id: 50023[/import]

Ok Josh…

This code is updated to use the new scaling you just post…

It gets me a the correct pink box on the Simulator …
but still gets me a black rectangle on my iPhone 3GS.

(build #600 of course)

[edited with small code update, still same result, though.]

local baseDir = system.DocumentsDirectory  
local fileName ="pic\_" .. os.time() .. ".jpg";  
  
--[[###########################################]]--  
-- white background.  
local thisRect = display.newRect (-50, -50, display.contentWidth+100, display.contentHeight+100);  
thisRect:setFillColor(255, 255, 255);  
  
--[[###########################################]]--  
-- create a pink rectangle and then create an image file with it.  
local myGroup = display.newGroup ();  
local thisMainRect = display.newRect (50,50,150, 100);  
thisMainRect:setFillColor(220,200,200);  
thisMainRect.x = display.contentWidth/2  
thisMainRect.y = display.contentHeight/2  
myGroup:insert (thisMainRect);  
  
display.save( myGroup, fileName, baseDirectory )   
myGroup:removeSelf();  
myGroup = nil;  
--[[###########################################]]--  
-- reload the pink rectangle image ...  
local newGroup = display.newGroup();  
local tmpImage= display.newImage(fileName, system.DocumentsDirectory)  
newGroup:insert(tmpImage);  
local xScale = 0.5 \* (newGroup.width / tmpImage.width)  
local yScale = 0.5 \* (newGroup.height / tmpImage.height)  
tmpImage:scale(xScale, yScale)  
tmpImage.x = display.contentWidth / 2  
tmpImage.y = display.contentHeight / 2  
  
-- now do a display.save of the pink rectangle  
-- this simulates bringing in a photo.jpg from the camera roll and then saving it:  
display.save( newGroup, fileName, baseDirectory )   
  
newGroup:removeSelf();  
newGroup = nil;  
  
--[[###########################################]]--  
-- finally:  
-- display the final reloaded image back:  
local tmpImg = display.newImage (fileName, system.DocumentsDirectory, display.contentWidth/2, display.contentHeight/2);  
tmpImg.x = display.contentWidth/2;  
tmpImg.y = display.contentHeight/2;  
  

Where am I going wrong here? :slight_smile:

THANKS!
[import]uid: 13859 topic_id: 12957 reply_id: 50024[/import]

Oh wait. After re-reading your post, I think I know what the issue is. The display.save() and display.captureScreen() always fail to capture the image on the first rendered frame on iOS and Android. We’ve seen this issue before and appears to be an OpenGL ES issue that we haven’t figured out how to work-around yet in Corona.

You can work-around it by making sure to capture the image on any subsequent frames. For example, try moving your code to an tap event. Then your black screen capture image will go away.

[import]uid: 32256 topic_id: 12957 reply_id: 50036[/import]

Alright, I extrapolated out and put the whole “reload of the pink rect” into a timer …

Still just a black rect… no pink.

local baseDir = system.DocumentsDirectory  
local fileName ="pic\_" .. os.time() .. ".jpg";  
  
--[[###########################################]]--  
-- white background.  
local thisRect = display.newRect (-50, -50, display.contentWidth+100, display.contentHeight+100);  
thisRect:setFillColor(255, 255, 255);  
  
--[[###########################################]]--  
-- create a pink rectangle and then create an image file with it.  
local myGroup = display.newGroup ();  
local thisMainRect = display.newRect (50,50,150, 100);  
thisMainRect:setFillColor(220,200,200);  
thisMainRect.x = display.contentWidth/2  
thisMainRect.y = display.contentHeight/2  
myGroup:insert (thisMainRect);  
  
display.save( myGroup, fileName, baseDirectory )   
myGroup:removeSelf();  
myGroup = nil;  
local tmpFunc = function ()  
 --[[###########################################]]--  
 -- reload the pink rectangle image ...  
 local newGroup = display.newGroup();  
 local tmpImage= display.newImage(fileName, system.DocumentsDirectory)  
 newGroup:insert(tmpImage);  
 local xScale = 0.5 \* (newGroup.width / tmpImage.width)  
 local yScale = 0.5 \* (newGroup.height / tmpImage.height)  
 tmpImage:scale(xScale, yScale)  
 tmpImage.x = display.contentWidth / 2  
 tmpImage.y = display.contentHeight / 2  
  
 -- now do a display.save of the pink rectangle  
 -- this simulates bringing in a photo.jpg from the camera roll and then saving it:  
 display.save( newGroup, fileName, baseDirectory )   
  
 newGroup:removeSelf();  
 newGroup = nil;  
  
 --[[###########################################]]--  
 -- finally:  
 -- display the final reloaded image back:  
 local tmpImg = display.newImage (fileName, system.DocumentsDirectory, display.contentWidth/2, display.contentHeight/2);  
 tmpImg.x = display.contentWidth/2;  
 tmpImg.y = display.contentHeight/2;  
  
end  
  
timer.performWithDelay (100, tmpFunc);  

… I’m still stumped. :wink: [import]uid: 13859 topic_id: 12957 reply_id: 50080[/import]

… Yeah, that code above doesn’t work in 591 either, so I dunno what the deal is. I would think if it works in the sim, it should show correctly on the phone, but eh. The funny thing is that it’s not even the problem I’m trying to deal with. *grin* Oh well. [import]uid: 13859 topic_id: 12957 reply_id: 50081[/import]

Ah… I had to extrapolate another level… This is working on the phone. Will move to the iPad in a minute…

local baseDir = system.DocumentsDirectory  
local fileName ="pic\_" .. os.time() .. ".jpg";  
  
--[[###########################################]]--  
-- white background.  
local thisRect = display.newRect (-50, -50, display.contentWidth+100, display.contentHeight+100);  
thisRect:setFillColor(255, 255, 255);  
thisRect.tmpFunc = function ()  
  
 --[[###########################################]]--  
 -- create a pink rectangle and then create an image file with it.  
 local myGroup = display.newGroup ();  
 local thisMainRect = display.newRect (50,50,150, 100);  
 thisMainRect:setFillColor(220,200,200);  
 thisMainRect.x = display.contentWidth/2  
 thisMainRect.y = display.contentHeight/2  
 myGroup:insert (thisMainRect);  
  
 display.save( myGroup, fileName, baseDirectory )   
  
 local tmpFunc2 = function ()  
 myGroup:removeSelf();  
 myGroup = nil;  
 --[[###########################################]]--  
 -- reload the pink rectangle image ...  
 local newGroup = display.newGroup();  
 local tmpImage= display.newImage(fileName, system.DocumentsDirectory)  
 newGroup:insert(tmpImage);  
 local xScale = 0.5 \* (newGroup.width / tmpImage.width)  
 local yScale = 0.5 \* (newGroup.height / tmpImage.height)  
 tmpImage:scale(xScale, yScale)  
 tmpImage.x = display.contentWidth / 2  
 tmpImage.y = display.contentHeight / 2  
  
 -- now do a display.save of the pink rectangle  
 -- this simulates bringing in a photo.jpg from the camera roll and then saving it:  
 display.save( newGroup, fileName, baseDirectory )   
  
 newGroup:removeSelf();  
 newGroup = nil;  
  
 --[[###########################################]]--  
 -- finally:  
 -- display the final reloaded image back:  
 local tmpImg = display.newImage (fileName, system.DocumentsDirectory, display.contentWidth/2, display.contentHeight/2);  
 tmpImg.x = display.contentWidth/2;  
 tmpImg.y = display.contentHeight/2 + 100;  
 return true;  
 end  
-- thisRect:removeEventListener ("tap", thisRect.tmpFunc);  
-- thisMainRect:addEventListener ("tap", tmpFunc2);  
 timer.performWithDelay (1, tmpFunc2);  
  
 return true;  
end  
--thisRect:addEventListener ("tap", thisRect.tmpFunc);  
timer.performWithDelay (1, thisRect.tmpFunc);  

Alright [import]uid: 13859 topic_id: 12957 reply_id: 50083[/import]

OK! I’ve finally got working test code that fails.

local baseDir = system.DocumentsDirectory  
local fileName ="pic\_" .. os.time() .. ".jpg";  
  
--[[###########################################]]--  
-- white background.  
local thisRect = display.newRect (-50, -50, display.contentWidth+100, display.contentHeight+100);  
thisRect:setFillColor(255, 255, 255);  
local tmpFunc = function ( event )  
  
 local newGroup = display.newGroup();  
 local tmpImage = event.target  
 newGroup:insert(tmpImage);  
 local xScale = 0.35 \* (newGroup.width / tmpImage.width)  
 local yScale = 0.35 \* (newGroup.height / tmpImage.height)  
 tmpImage:scale(xScale, yScale)  
 tmpImage.x = display.contentWidth / 2  
 tmpImage.y = display.contentHeight / 2  
  
 -- now do a display.save of the pink rectangle  
 -- this simulates bringing in a photo.jpg from the camera roll and then saving it:  
 display.save( newGroup, fileName, baseDirectory )   
  
 newGroup:removeSelf();  
 newGroup = nil;  
  
 --[[###########################################]]--  
 -- finally:  
 -- display the final reloaded image back:  
 local tmpImg = display.newImage (fileName, system.DocumentsDirectory, display.contentWidth/2, display.contentHeight/2);  
 tmpImg.x = display.contentWidth/2;  
 tmpImg.y = display.contentHeight/2;  
 tmpImg:scale(xScale, yScale)  
 return true;  
end  
media.show( media.SavedPhotosAlbum, tmpFunc )  
  

And my config.lua:

application =  
{  
 content =  
 {  
 width = 320,  
 height = 480,  
 scale = "letterbox",  
 imageSuffix =  
 {  
 ["@2"] = 2,  
 },  
  
 },  
}   

This just starts an app that launches the camera roll selector. When you select it, it imports the image, then saves it to the app directory … and then reloads it … (As if you imported a picture and now want to do something with it.)

The .5 scaling doesn’t work when you’re importing a photo into the ipad, it chops some … so you have to go smaller to get the whole thing. For testing, I just emailed myself a landscape and a horizontal photo from my iphone and saved them to the ipad’s camera roll.

I think the general point is:
If you have an image that is SMALLER (or scaled to be smaller) than the screen… as the only element in a group, there’s some sort of offset that’s occurring. Likely due to iPad scaling ???
Also… i tried to import a SQUARE image and there is no issue. This only occurs on rectangular image imports.
? :wink: [import]uid: 13859 topic_id: 12957 reply_id: 50091[/import]

Hi Kenn,

Let’s take a step back here. Do you want an “exact” copy of the image in the device’s photo library in your document’s directory? As in not scaled at all? If so, then we can make an adjustment to display.save(event.target) where if it is given an image object, then just copy the image to file instead of doing a screenshot via OpenGL. All other objects, especially groups, would be screen-shotted. From a performance perspective, this would be better too. So, would that help you?
[import]uid: 32256 topic_id: 12957 reply_id: 50255[/import]

“Do you want an ‘exact’ copy of the image in the device’s photo library in your document’s directory? As in not scaled at all?”

Indeed, I do just want to copy a photo from the library (or if someone takes a pic with the camera) and store it directly to my documents directory in the app.

SO: YES, ABSOLUTELY! :slight_smile: THAT WOULD BE AWESOME!!! :slight_smile:
[import]uid: 13859 topic_id: 12957 reply_id: 50270[/import]

… Just thought I’d check to see if we were getting anywhere with this little addition? :slight_smile:

Best,
~~Kenn [import]uid: 13859 topic_id: 12957 reply_id: 51374[/import]

Hi Kenn,

I apologize for not getting back to you. Ansca has prior commitments that must be addressed first before working on what I’ve proposed. In the mean-time, I’m sure we can get the existing version of the Corona SDK to do what you want, I just don’t have the time to test this right now. Especially since I don’t have the ability to test on iOS right now (I’m the Android guy here at Ansca). I’ll try to find someone here at Ansca who does.

One though on your existing Lua script, try doing a display.save() on the tmpImage and not the group. [import]uid: 32256 topic_id: 12957 reply_id: 51383[/import]

Hi Joshua,

With any of the builds I have tried, if I scale an image and then save display.save just that image, I get the regular size with a smaller image inside it – the rest of the image is BLACK.

IE, it saves a BLACK rectangle of the original size and then places the smaller scaled image of the correct size within that black rectangle.

In other words, display.save on images is super buggy and unusable in it’s current form. *shrug*
[import]uid: 13859 topic_id: 12957 reply_id: 51388[/import]

@kennw,

The problem with black image in your original example code was mentioned by Josh and caused by trying to do a display.save in the main.lua thread before the event loop was running. Corona waits until the end of the code block before it sends display commands to the openGL engine. The black object was because the object was capture before it had rendered on the screen.

I modified your code to call display.save after a short delay. The timer is enough to cause the code to execute after the event loop is running and it captures the pink rectangle.

--[[###########################################]]--  
-- create a pink rectangle and then create an image file with it.  
local myGroup = display.newGroup ();  
local thisMainRect = display.newRect (50,50,150, 100);  
thisMainRect:setFillColor(220,200,200);  
thisMainRect.x = display.contentWidth/2  
thisMainRect.y = display.contentHeight/2  
myGroup:insert (thisMainRect);  
  
--display.save( myGroup, fileName, baseDirectory )   
timer.performWithDelay (1,  
 function()  
 display.save( myGroup, fileName, baseDirectory )  
 myGroup:removeSelf();  
 myGroup = nil;  
 end )  
  
--myGroup:removeSelf();  
--myGroup = nil;  

I’ll take a look at the display.save to see if we still have problems.

-Tom [import]uid: 7559 topic_id: 12957 reply_id: 51760[/import]

@Tom

Yeah, I just opened this and was hopeful for a minute there… made a couple changes, but still, if I display.save a 160x240 image in the iPad simulator, the resulting saved image has a 2 pixel black stripe down the left side.

Also, a “display.save” of just the 160x240 image seems to get me a resulting file size of 373x640. (I’m not scaling the image before the save. xScale and yScale = 1.

Yes, this occurs even when abstracting the save layer into it’s own timer that executes 100 ms after the resize… which did work OK with the previous test cases.

Unfortunately, that’s really not very effective or useful for much. :wink: I concede using just photos or full screenshots, this might be ok… but I’m working with various sizes which should/is said to be the benefit of display.save. *shrug*

Note that it shows the image that I’m display.save’ing on-screen correctly. It’s the resulting file that is not correct. (And I’m looking in the project sandbox to confirm the incorrectness of the display.save result file.)
Best wishes,
~~Kenn [import]uid: 13859 topic_id: 12957 reply_id: 52250[/import]

Edit: Solution posted below sample code:

No one is complaining about this, so I must be doing something really silly…hopefully someone can point it out for me:

Using:
media.show(media.PhotoLibrary, onComplete)

When I pick a full size photo, image resize (see below) is working perfectly, BUT it seems the img (being larger than iphone 4 display) has already rendered partially off-screen & so my scale {size1to2} func, happened on the TRUNCATED part of the pic

– my scaling code is running too late to get the whole pict?

In short, what’s being saved to disk is the SCALED bottom right corner of the whole picture.

Sample code:
[lua]local onComplete = function(v_event2)
local imgObj = v_event2.target
if not imgObj then – user hit cancel; load last image
return true
end
– print(‘imgObj.width=’…imgObj.width…’ imgObj.height=’…imgObj.height)
if imgObj.width ~= 84 or imgObj.height ~= 84 then
img.size1to2(imgObj, {84,84})
end – resize is working perfectly, BUT:

– it seems the img already rendered partially off-screen
– and so my scale {size1to2} func, happend on the TRUNCATED part of the pic
– ie too late

local group = newGroup()
group.x = 0
group.y = 0
group:insert(imgObj)

local filename = timestamp()
img.storeImg(group, filename) --now store it as a file in
imgObj:removeSelf() – destroy the image

loadPic(filename) – loads 84x84 truncated copy
end

media.show(media.PhotoLibrary, onComplete)[/lua]

Does anyone know how to work around this??

Oh nevermind…I just figured out what you guys are saying above about the next frame…my “scale” doesn’t happen until the next redraw and so I’m saving too soon.

Got it…I’ll try that now. [import]uid: 6175 topic_id: 12957 reply_id: 52890[/import]

can you use display.save() and display.captureScreen() and post the image to Facebook?

Hey I just had to ask?

Thanks

DoubleSlashDesign.com
Larry [import]uid: 11860 topic_id: 12957 reply_id: 52917[/import]

Larry,

Unfortunately, Corona cannot send images to facebook. Corona can only send “links” to photos on facebook as shown in our SDK’s “Networking\Facebook” sample app. [import]uid: 32256 topic_id: 12957 reply_id: 52928[/import]

@Joshua Quick:

How about sending captured images for e-mail? Several use case here…

  1. Capture an image and bring it up in the device’s default e-mail with it attached

  2. Capture an image, listView reads it, touch and bring up the device’s default e-mail with it attached

This is being widely requested.

Thanks! [import]uid: 66859 topic_id: 12957 reply_id: 52940[/import]

MeApps,

Corona can’t send e-mail attachments either, but that feature is on our wish list. [import]uid: 32256 topic_id: 12957 reply_id: 52995[/import]

Joshua,

like the post title says: We’ll love you forever!
[import]uid: 66859 topic_id: 12957 reply_id: 52997[/import]