How to lazyload a Image

I am using display.newImage( name , system.DocumentsDirectory , true ) to make a image object to show in front .

I want change the file from remote server. So  I  try to load a black.png at first , after donwload realy png file form server , I want exchange old img to use new png file  the sample code like this

function load_img(remote_file)

 local  img_tmp  = display.newImage( ‘black.png’ , system.DocumentsDirectory , true )

 download_function = function (remote_file)

     local saveName = “/img/save.png”

     download_finished = function (event)

         local  img_remote  = display.newImage( saveName, system.DocumentsDirectory , true )

        img_tmp   = img_remote  

    end 

   

   network.download(

       remote_file,

       “GET”,

       download_finished ,

       { progress=false },–params

       (saveName),–保存先

        system.DocumentsDirectory

     )

    

 end

  return img_tmp

end 

local pic = load_img("http://12.212.121.12/a.png")

local t = display.newGroup()

t:insert(pic)

The Problem is , after I download a png , I can’t change the tmp png . 

please help 

Once you download an image and display it, you should consider that image locked (on your persistent storage).  This is not exactly right, but detecting when you can overwrite the image is hard.  You are better off doing this:

  1. Download images in the temporary folder.

  2. Give them unique names.

  3. (If space is a concern) Set up a timer based function to occasionally go through and ‘try’ to delete images you’re not using any more.

PS - The above is a gross simplification of what I did for this app, but in essence I did this same things:

https://itunes.apple.com/us/app/menume/id700326215?mt=8

You cannot swap images like that.  You need to create the new one in it’s own object, then remove the temporary one using

display.remove(img_tmp)

img_tmp = nil

after that you can assign your new image to img_tmp

You cannot swap images like that.  You need to create the new one in it’s own object, then remove the temporary one using

Rob: That was my understanding as well (probably influenced by some of Corona’s excellent tutorials). But our own <roaminggamer>, who posted above, suggested using the below approach instead. I haven’t tried it myself, but it seems promising.

--print( "Displaying response image file" ) curImg.fill = { type = "image", baseDir = event.response.baseDirectory, filename = event.response.filename }

http://forums.coronalabs.com/topic/54861-return-loadremoteimage-from-url-or-load-locally-if-exists/

thank you every answer, I will try It 。

I noticed the answer I gave in that forum post (link above) used my exists() extension to io.*, but I forgot to give the code.  So, if you use the code from that link, you’ll also need this:

function io.exists( fileName, base ) local base = base or system.DocumentsDirectory local fileName = fileName if( base ) then fileName = system.pathForFile( fileName, base ) end if not fileName then return false end local f=io.open(fileName,"r") if (f == nil) then return false end io.close(f) return true end

local easyRemoteImage = function( curImg, fileName, imageURL ) if( string.match( imageURL, "http" ) == nil ) then imageURL = "http:" .. imageURL end if( io.exists( fileName, system.TemporaryDirectory ) ) then curImg.fill = { type = "image", baseDir = system.TemporaryDirectory, filename = fileName } return end local function networkListener( event ) if ( event.isError ) then --print( "Network error - download failed" ) elseif ( event.phase == "began" ) then --print( "Progress Phase: began" ) elseif ( event.phase == "ended" ) then --print( "Displaying response image file" ) curImg.fill = { type = "image", baseDir = event.response.baseDirectory, filename = event.response.filename } end end local params = {} params.progress = false network.download( imageURL, "GET", networkListener, params, fileName, system.TemporaryDirectory ) end

Usage example:

-- pseudo code local tmp = newRect( ... ) local imgUrl = "..." local fileName = "something.png" easyRemote( tmp, fileName, imgURL )

Thank you roaminggamer, your code is great , sovled my problem  :slight_smile:

That’s true to a point.  The fact that everyone has Pro now will take me some time to get used to :slight_smile:

But the problem with using fill is it doesn’t change shape when you change the image.  As long as they are the same shape, you’re good.

Rob

Once you download an image and display it, you should consider that image locked (on your persistent storage).  This is not exactly right, but detecting when you can overwrite the image is hard.  You are better off doing this:

  1. Download images in the temporary folder.

  2. Give them unique names.

  3. (If space is a concern) Set up a timer based function to occasionally go through and ‘try’ to delete images you’re not using any more.

PS - The above is a gross simplification of what I did for this app, but in essence I did this same things:

https://itunes.apple.com/us/app/menume/id700326215?mt=8

You cannot swap images like that.  You need to create the new one in it’s own object, then remove the temporary one using

display.remove(img_tmp)

img_tmp = nil

after that you can assign your new image to img_tmp

You cannot swap images like that.  You need to create the new one in it’s own object, then remove the temporary one using

Rob: That was my understanding as well (probably influenced by some of Corona’s excellent tutorials). But our own <roaminggamer>, who posted above, suggested using the below approach instead. I haven’t tried it myself, but it seems promising.

--print( "Displaying response image file" ) curImg.fill = { type = "image", baseDir = event.response.baseDirectory, filename = event.response.filename }

http://forums.coronalabs.com/topic/54861-return-loadremoteimage-from-url-or-load-locally-if-exists/

thank you every answer, I will try It 。

I noticed the answer I gave in that forum post (link above) used my exists() extension to io.*, but I forgot to give the code.  So, if you use the code from that link, you’ll also need this:

function io.exists( fileName, base ) local base = base or system.DocumentsDirectory local fileName = fileName if( base ) then fileName = system.pathForFile( fileName, base ) end if not fileName then return false end local f=io.open(fileName,"r") if (f == nil) then return false end io.close(f) return true end

local easyRemoteImage = function( curImg, fileName, imageURL ) if( string.match( imageURL, "http" ) == nil ) then imageURL = "http:" .. imageURL end if( io.exists( fileName, system.TemporaryDirectory ) ) then curImg.fill = { type = "image", baseDir = system.TemporaryDirectory, filename = fileName } return end local function networkListener( event ) if ( event.isError ) then --print( "Network error - download failed" ) elseif ( event.phase == "began" ) then --print( "Progress Phase: began" ) elseif ( event.phase == "ended" ) then --print( "Displaying response image file" ) curImg.fill = { type = "image", baseDir = event.response.baseDirectory, filename = event.response.filename } end end local params = {} params.progress = false network.download( imageURL, "GET", networkListener, params, fileName, system.TemporaryDirectory ) end

Usage example:

-- pseudo code local tmp = newRect( ... ) local imgUrl = "..." local fileName = "something.png" easyRemote( tmp, fileName, imgURL )

Thank you roaminggamer, your code is great , sovled my problem  :slight_smile:

That’s true to a point.  The fact that everyone has Pro now will take me some time to get used to :slight_smile:

But the problem with using fill is it doesn’t change shape when you change the image.  As long as they are the same shape, you’re good.

Rob