Having trouble with media.selectPhoto( )

Hi Corona Community,

I’m still relatively new to Corona, and am still learning various aspects of it. Today, I have a question related to media.selectPhoto().

Some features of my app include:

  1.  a display object, which has its own state

  2.  which is also a listener itself, and when clicked on, fires media.selectPhoto( ) to replace itself with a image of the user’s choice.

  3.  a separate module to store the image, so that it can be retrieved later

  4.  and a toggle button to alter the state of the object.

My goal is that once an image is selected via media.selectPhoto( ), the app will display that image instead of the original display object (in this case a green square) when prompted for the 2nd time.

My problem is, once I upload an image, when I try to display that image after clicking the toggle button, Corona raises an error instead, claiming that the “eventListener is nil”, which doesn’t exactly makes too much sense to me.

Please help! Many thanks in advance!
KC

–main.lua–

display.setStatusBar(display.HiddenStatusBar) local composer = require("composer") composer.gotoScene("uploadimage")

–uploadimage.lua–

local d = require("data") local composer = require("composer") local scene = composer.newScene() local \_view local image local toggleButton local \_W , \_H = display.contentWidth , display.contentHeight local \_CX, \_CY = display.contentWidth/2, display.contentHeight/2 function scene:create(event) \_view = self.view initBackground() initImage("green") initToggleButton() end function initBackground() local background = display.newRect(\_CX, \_CY, \_W, \_H) background:setFillColor(1) \_view:insert(background) end function initImage(color) if (image) then image:removeSelf() image = nil end if (color == "green" and d.library.image) then image = d.library.image else image = display.newRect(240, \_CY, 160, 160) if (color == "green") then image:setFillColor(0,1,0) elseif (color == "red") then image:setFillColor(1,0,0) end end image.color = color image:addEventListener("tap", uploadImage) \_view:insert(image) end function uploadImage() if (image.color == "green") then timer.performWithDelay(100, function() media.selectPhoto{listener = updateImage, mediaSource = media.PhotoLibrary} end) end end function updateImage(event) local \_image = event.target if (\_image) then image:removeSelf() image = nil image = \_image image.x = 240 image.y = \_CY image.width = 160 image.height = 160 image.color = "green" image:addEventListener("tap", uploadImage) d.library.image = image \_view:insert(image) end end function initToggleButton() toggleButton = display.newCircle(480, \_CY, 60) toggleButton:setFillColor(0,0,1) toggleButton:addEventListener("tap", toggle) \_view:insert(toggleButton) end function toggle() print(image.color) if (image.color == "green") then initImage("red") elseif (image.color == "red") then initImage("green") end end scene:addEventListener("create", scene) return scene

–data.lua–

local M = {} M.library = { image } return M

If you want to replace the ‘image’ used by an existing imagerect or other display object, set the fill as per this article.

https://coronalabs.com/blog/2013/11/07/tutorial-repeating-fills-in-graphics-2-0/

(ignore title and focus on the fill setting part of the article, not repeating)

object.fill = { type="image", filename="corona-logo.png" }

It sounds like you’re deleting the object and making a new one instead?  If you replace the existing object’s fill, then its touch listener is retained.  Otherwise you need to add a new one for the new object.

More docs:

https://docs.coronalabs.com/daily/api/

https://docs.coronalabs.com/daily/api/type/ShapeObject/fill.html

@Roaminggamer

Am I missing something, because as far as I can tell with

object.fill = { type="image", filename="corona-logo.png" }

you need the actual filename. However, I read in various sources that there is no way to retrieve the filename from an image obtained by media.selectPhoto( ), so I am little confused…

I also tried removing the touch listener, and later add a new one, but that didn’t seem to work either…

That’s not right.  When you code this you (optionally) tell it where to place the photo (typically in temporary or documents folder) and what name to give the file.

https://docs.coronalabs.com/daily/api/library/media/selectPhoto.html#destination-optional

Your code would look something like this:

local button = display.newRect( 120, 240, 80, 70 ) -- Selection completion listener local function onComplete( event ) local photo = event.target display.remove( photo ) -- don't keep the image created by media -- Fill the button instead button.fill = { type = "image", baseDir=system.TemporaryDirectory, filename="image.jpg" } end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename="image.jpg" } }) end button:addEventListener( "tap", pickPhoto )

@ Roaminggamer

That solved it, thanks!  :smiley:

If you want to replace the ‘image’ used by an existing imagerect or other display object, set the fill as per this article.

https://coronalabs.com/blog/2013/11/07/tutorial-repeating-fills-in-graphics-2-0/

(ignore title and focus on the fill setting part of the article, not repeating)

object.fill = { type="image", filename="corona-logo.png" }

It sounds like you’re deleting the object and making a new one instead?  If you replace the existing object’s fill, then its touch listener is retained.  Otherwise you need to add a new one for the new object.

More docs:

https://docs.coronalabs.com/daily/api/

https://docs.coronalabs.com/daily/api/type/ShapeObject/fill.html

@Roaminggamer

Am I missing something, because as far as I can tell with

object.fill = { type="image", filename="corona-logo.png" }

you need the actual filename. However, I read in various sources that there is no way to retrieve the filename from an image obtained by media.selectPhoto( ), so I am little confused…

I also tried removing the touch listener, and later add a new one, but that didn’t seem to work either…

That’s not right.  When you code this you (optionally) tell it where to place the photo (typically in temporary or documents folder) and what name to give the file.

https://docs.coronalabs.com/daily/api/library/media/selectPhoto.html#destination-optional

Your code would look something like this:

local button = display.newRect( 120, 240, 80, 70 ) -- Selection completion listener local function onComplete( event ) local photo = event.target display.remove( photo ) -- don't keep the image created by media -- Fill the button instead button.fill = { type = "image", baseDir=system.TemporaryDirectory, filename="image.jpg" } end local function pickPhoto( event ) media.selectPhoto( { mediaSource = media.SavedPhotosAlbum, listener = onComplete, origin = button.contentBounds, permittedArrowDirections = { "right" }, destination = { baseDir=system.TemporaryDirectory, filename="image.jpg" } }) end button:addEventListener( "tap", pickPhoto )

@ Roaminggamer

That solved it, thanks!  :smiley: