Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

How to save a remote image/picture to database or filesystem

I create a remote imageview, I want to save the remote image to database or filesystem.
I tried this code:


var img_url = "http://www.google.com/intl/en_ALL/images/srpr/logo1w.png";
var remote_image_view = Ti.UI.createImageView({
url:img_url
});
var db = Ti.Database.open("imgdb4");
db.execute('CREATE TABLE IF NOT EXISTS DATABASETEST (ID TEXT, IMAGE BLOB)');
db.execute('DELETE FROM DATABASETEST');

//add a listener, when the remote img has been download:
remote_image_view.addEventListener("load",function(e){
//after download
Ti.API.info(e.source.toBlob());//output: [INFO] [object TiBlob]
try{
//I tried use e.source.toBlob(), but looks not work
db.execute('INSERT INTO DATABASETEST (ID, IMAGE) VALUES(?,?)',"picture name",e.source.toBlob());
}catch(E){
//I got error,
alert(E);
}
});
//add imageview to the window

Ti.UI.currentWindow.add(remote_image_view);

var btn_show_db_image = Titanium.UI.createButton({
title:'I am a Button',
width:200,
height:40,
top:60
});

btn_show_db_image.addEventListener("click",function(e){
try{
//Try to retrive the image from database and use for another imageview
var rows = db.execute('SELECT * FROM DATABASETEST');
var db_image_view = Ti.UI.createImageView({
image:rows.fieldByName('IMAGE').toBlob()
});
rows.close();
Ti.UI.currentWindow.add(db_image_view);
}catch(E){
//my app crashed
alert(E);
}

});
Ti.UI.currentWindow.add(btn_show_db_image);

— asked July 23rd 2010 by Ding Hua
  • blob
  • database
  • file
  • image
  • remote
  • save
0 Comments

7 Answers

  • Accepted Answer

    I have a function made for this:

    
    
    var get_remote_file =  function(filename, url, fn_end, fn_progress ) {
        var file_obj = {file:filename, url:url, path: null};
    
        var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
        if ( file.exists() ) {
            file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
            fn_end(file_obj);
        }
        else {
    
            if ( Titanium.Network.online ) {
                var c = Titanium.Network.createHTTPClient();
    
                c.setTimeout(10000);
                c.onload = function()
                {
    
                    if (c.status == 200 ) {
    
    
                        var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
                        f.write(this.responseData);
                        file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
                    }
    
                    else {
                        file_obj.error = 'file not found'; // to set some errors codes
                    }
                    fn_end(file_obj);
    
                };
                c.ondatastream = function(e)
                {
    
                    if ( fn_progress ) fn_progress(e.progress);
                };
                c.error = function(e)
                {
    
                    file_obj.error = e.error;
                    fn_end(file_obj);
                };
                c.open('GET',url);
                c.send();            
            }
            else {
                file_obj.error = 'no internet';
                fn_end(file_obj);
            }
    
    
        }
    };
    
    — answered August 25th 2010 by Dan Tamas
    permalink
    11 Comments
    • greate function! works perfect on Iphone, but Android failed :( with error: java.lang.NullPointerException:uriString

      any ideas?

      — commented August 26th 2010 by Petr Cervenka
    • I tried calling this function this way, but it didn't work. Can you assist?

      get_remote_file('iphoneimage.jpg','http://nickbodmer.com/temp/iphoneimage.jpg');

      — commented December 3rd 2010 by Nick Bodmer
    • can someone post a little example for this function?

      — commented December 20th 2010 by ben roe
    • absolutely great solution! thanks for that. take a beer ;)

      — commented January 23rd 2011 by Sebastian Klaus
    • usage is like get_remote_file("file.txt", strCategoryFileUrl, Ti.API.info, null);

      — commented March 16th 2011 by Dirk Krause
    • Thx for the Code, Dan!

      I added a slight variation. My version has a boolean 'AlwaysLoad'. If set to true, it assumes that there is an initial file that can be used while in offline mode, and always gets the current file from the server while online. If set to offline again, it uses the actual file.

      var get_remote_file = function(filename, url, fn_end, fn_progress, boolAlwaysload){
          var file_obj = {
              file: filename,
              url: url,
              path: null
          };
      
          var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
          if (file.exists() && !boolAlwaysload){
              file_obj.path = Titanium.Filesystem.applicationDataDirectory + Titanium.Filesystem.separator;
              fn_end(file_obj);
          }
          else{
              if (Titanium.Network.online){
                  var c = Titanium.Network.createHTTPClient();
      
                  c.setTimeout(10000);
                  c.onload = function()
                  {
      
                      if (c.status == 200){
                          log('finished downloading ' + filename + ' from ' + url);
      
                          var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
                          f.write(this.responseData);
                          file_obj.path = Titanium.Filesystem.applicationDataDirectory + Titanium.Filesystem.separator;
                      }
      
                      else{
                          file_obj.error = 'file not found';
                          // to set some errors codes
                      }
                      fn_end(file_obj);
      
                  };
                  c.ondatastream = function(e)
                  {
                      log('progress ' + filename + ':' + e.progress);
                      if (fn_progress) fn_progress(e.progress);
                  };
                  c.error = function(e)
                  {
                      log('error ' + e.error);
                      file_obj.error = e.error;
                      fn_end(file_obj);
                  };
                  c.open('GET', url);
                  c.send();
              }
              else{
                  if (file.exists() && boolAlwaysload){
                      file_obj.path = Titanium.Filesystem.applicationDataDirectory + Titanium.Filesystem.separator;
                      fn_end(file_obj);
                  }
                  else
                  {
                      file_obj.error = 'no internet';
                      fn_end(file_obj);
                  }
              }
          }
      };
      

      — commented March 16th 2011 by Dirk Krause
    • It took me a little bit of time to figure out how this works, but here is a working app.js that you can plug into a new file and test with.

      /*
       * A good example of caching images to the device.
       */
      
      
      var win = Ti.UI.createWindow();
      win.addEventListener("open", onOpen);
      win.open();
      
      function onOpen(e){    
          get_remote_file("Wiki.png", "http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png", onComplete, onProgress)
      }
      
      function onComplete(file){
          var img = Ti.UI.createImageView({
              image:  file.path + file.file
          });
          win.add(img);
      }
      function onProgress(progress){
          TI.API.info("progress being made " + progress);
      }
      
      
      function get_remote_file(filename, url, fn_end, fn_progress ) {
          var file_obj = {file:filename, url:url, path: null};
      
          var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
          if ( file.exists() ) {
              file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
              fn_end(file_obj);
          }
          else {
      
              if ( Titanium.Network.online ) {
                  var c = Titanium.Network.createHTTPClient();
      
                  c.setTimeout(10000);
                  c.onload = function()
                  {
      
                      if (c.status == 200 ) {
      
      
                          var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
                          f.write(this.responseData);
                          file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
      
                      }else{
                          file_obj.error = 'file not found'; // to set some errors codes
                      }
                      fn_end(file_obj);
      
                  };
                  c.ondatastream = function(e)
                  {
      
                      if ( fn_progress ) fn_progress(e.progress);
                  };
                  c.error = function(e)
                  {
      
                      file_obj.error = e.error;
                      fn_end(file_obj);
                  };
                  c.open('GET',url);
                  c.send();           
              }
              else {
                  file_obj.error = 'no internet';
                  fn_end(file_obj);
              }
      
      
          }
      };
      

      The file_object is passed to the fn_complete callback. while testing, be sure to delete the app from simulator, because if its already downloaded a file with the wrong data, or no image data, the next time you try to test, the file won't be re-downloaded.

      Enjoy!
      Aaron @codecommando

      — commented February 19th 2012 by Digital Surgeons
    • I really like this function, though it does not work on the actual device. I have tried other functions as well. Including ones I have made myself and while they all worked in the emulator, none work on the actual device.
      does anybody know why?

      — commented February 27th 2012 by brandon martin
    • I'm experiencing persistent problems with this function in any version after 1.8., including the new 2. GA release. I'd be really really appreciative if someone could shine any light on what could resolve this issue.. what I see happening (not happening rather) is that the onLoad() is not being fired - and the files don't appear to be saving.

      I've tried this with a blank project as well as in my fully fledged projects and it won't work after 1.8.* :( Doesn't seem to be synchronous anymore, is this because of the newer versions?

      
      var win = Ti.UI.currentWindow;
      
      var appframeworkstorage = Titanium.Filesystem.applicationDataDirectory + '/';
      
      var get_remote_file = function(filename, url, forced, fn_end, fn_progress )
      {
          var file_obj = {file:filename, url:url, path: null};
      
          var file = Titanium.Filesystem.getFile(appframeworkstorage,filename);
          if (file.exists() && forced == "0")
          {
              file_obj.path = appframeworkstorage;
              fn_end(file_obj);
          }
          else
          {
              if(Titanium.Network.online)
              {
                  var c = Titanium.Network.createHTTPClient();
                  c.setTimeout(10000);
                  c.onload = function(e)
                  {
                      alert('onLoad');
                      if (c.status == 200 )
                      {
                          var f = Titanium.Filesystem.getFile(appframeworkstorage,filename);
                          f.write(this.responseData);
                          f.remoteBackup = false;
                          file_obj.path = appframeworkstorage;
                          fn_end(file_obj);
                          if(f.extension() == "zip")
                          {
                              var zipfile = require("zipfile");
                              var appDir = Ti.Network.decodeURIComponent(appframeworkstorage).replace('file://localhost', '');
                              zipfile.extract(appDir+filename, appDir);                                    
                              zipfile = false;
                              appDir = false;
                              f.deleteFile();
                          }
                          f = false;
                      }
                      else
                      {
                          file_obj.error = 'file not found'; // to set some errors codes
                          fn_end(file_obj);
                      }
                  };
                  c.ondatastream = function(e)
                  {
                      if ( fn_progress ) 
                      fn_progress(e.progress);
                  };
                  c.onreadystatechange = function(e)
                  {
                      //
                  };
                  c.error = function(e)
                  {
                      file_obj.error = e.error;
                      fn_end(file_obj);
                      alert('Error with Download');
                  };
                  c.open('GET',url, false);
                  c.send();
                  c = false;           
              }
              else
              {
                  file_obj.error = 'no internet';
                  fn_end(file_obj);
              }
          }
      };
      
      for (var d=0;d<200;d++)
      {
          Ti.API.info('Starting File Download ' + d);
          get_remote_file(
              'http://www.google.com',
              'test' + d + '.html',
              '1',
              function(fileobj)
              {
                  Ti.API.info(fileobj);
              }, 
              function(fileprogress)
              {
                  Ti.API.info(fileprogress);
              }
          );
      
      }
      

      — commented April 17th 2012 by P Sweeney
    • Hey P!

      Did you manage to fix this? I bumped into this problem as well. The onprogress returns with 1 indicating full progress immeditately. But ofcourse it didnt work out…

      Would be great if you could post your solution to this >1.8

      cheers, Roeland

      — commented October 5th 2012 by Roeland P
    • This is working for me at the moment:

      var get_remote_file = function(filename, url, forced, fn_error, fn_progress, fn_complete)
      {
          var file_obj = {file:filename, url:url + '/' + filename, path: null};
      
          var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
          if (file.exists() && forced == "0")
          {
              file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
              //fn_end(file_obj);
              if ( fn_complete ) fn_complete('complete');
          }
          else
          {
              if(Titanium.Network.online == true)
              {
                  //alert('Going to download file now');
                  var c = Titanium.Network.createHTTPClient();
                  c.setTimeout(20000);
                  c.onload = function(e)
                  {
                      //alert('onload ' + filename);
                      if (c.status == 200 )
                      {
                          var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
                          f.write(this.responseData);
                          f.remoteBackup = false;
                          file_obj.path = Titanium.Filesystem.applicationDataDirectory;
                          //fn_end(file_obj);
      
                          f = false;
                          //f = null;
                          file = null;
                      }
                      else
                      {
                  file_obj.error = 'file not found'; // to set some errors codes
                         alert('File not found');
                  n_end(file_obj);
                      }
                      if ( fn_complete ) fn_complete('complete');
                  };
                  c.ondatastream = function(e)
                  {
                      //alert('ondatastream');
                      if ( fn_progress ) fn_progress(e.progress);
                  };
                  c.onerror = function(e)
                  {
                      //alert('Error downloading file: ' + filename);
                      file_obj.error = e.error;
                      f = null;
                      file = null;
                      fn_error(file_obj);
                  };
                  c.open('GET',url + '/' + filename);
                  //alert('about to send');
                  c.send();           
              }
              else
              {
                  file_obj.error = 'no internet';
                  alert('No connectivity.. ');
                  //fn_end(file_obj);
              }
          }
      };
      

      — commented October 5th 2012 by P Sweeney
  • Yop,

    Needs a bit of error handling but it's straightforward :

    getRemoteFile: function(file, remote) {
             var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,file);
             if (!f.exists()) {
                 var c = Titanium.Network.createHTTPClient();
                 c.onload = function() {
                     f.write(this.responseData);
                 }
                c.open('GET',remote, true);
                 c.send();         
             }
             return f.nativePath;
         }
    

    It takes an (filename, remote uri) as arguments , looks on the FS to see if it's there, else download it, store it and finally return the path on the file sytem as a string (absolute path, should be crossplatform).

    — answered November 28th 2011 by Gregory Boddin
    permalink
    0 Comments
  • hey everybody,

    i got a problem with the filesystem savings of titanium. i use this function:

    var c = Titanium.Network.createHTTPClient();
    
                c.onload = function() {
                    var f = Titanium.Filesystem.getFile('images/retailer/' + branch.newsId +".jpg");
                    if (!f.exists()) {
                        f.write(this.responseData);
                    }
    
                    addAnnotation(f.nativePath, branch, branchArray);
                };
                // open the client
                c.open('GET',url);
                // send the data
                c.send();
    

    everything works fine on emulator and he saves the pictures in the right folder but if i use this function on the iphone the photos wont be saved. i use the images on a map as a annotation but ill get the red dots everywhere.

    note:
    the images i already downloaded on the emulator will be shown on the map. just the new ones dont appear.

    anyone knows about this bug or is it a problem of the system rights ?

    best regards
    vitalij

    — answered January 26th 2011 by Vitalij Dadaschjanz
    permalink
    2 Comments
    • On the iPhone the resources folder is readonly. You need to write it on the application data folder

             var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
      

      — commented January 26th 2011 by Dan Tamas
    • thanks mate. everything worked fine

      — commented January 28th 2011 by Vitalij Dadaschjanz
  • Does "write" happen instantaneously?

    when I do this….

    var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
    if(f.exists()) { trace('file exists'); } else {trace("file doesnt exist");}
    

    It always says file not found. Maybe I have to wait a little before doing exist check?

    — answered May 26th 2011 by D Choi
    permalink
    0 Comments
  • here it is:

    get_remote_file =  function(
       'saved_on_the_device.html',
       'http://yahoo.com',
       function(fileobj){
    Ti.API.info(fileobj)
       alert('done')
     }, 
      function(progress){
    Ti.API.info(progress)
    }
    
     )
    

    If you already have the file on the device will serve what u have on the device else will save what it gets from the net

    — answered December 20th 2010 by Dan Tamas
    permalink
    1 Comment
    • Hi Dan,

      How do I get access to the file_obj path and file_obj file properties i.e..

      var file_obj = {file:filename, url:url, path: null};
      

      inside the function you posted previously?

      Also, I'm not sure I understand what you mean, by "if you already have the file on the device will serve what u have on the device else will save what it gets from the net".

      So what is the return value when calling the get_remote_file function when the file is already on the device?

      — commented April 3rd 2011 by Dennis Lo
  • With my code, I'm getting between 7-10 files downloaded before it decides to stop. There are 72 images to download, yet it decides to cut short at any given number.

    Any idea why this could be happening?

    
    var get_remote_file = function(filename, url, fn_end, fn_progress )
            {
                var file_obj = {file:filename, url:url, path: null};
    
                var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
                if ( file.exists() )
                {
                    file_obj.path = Titanium.Filesystem.applicationDataDirectory+Titanium.Filesystem.separator;
                    fn_end(file_obj);
                }
                else
                {
                    if ( Titanium.Network.online )
                    {
                        var c = Titanium.Network.createHTTPClient();
                        c.setTimeout(10000);
                        c.onload = function()
                        {
                            if (c.status == 200 )
                            {
                                var f = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,filename);
                                f.write(this.responseData);
                                file_obj.path = Titanium.Filesystem.applicationDataDirectory;
                                fn_end(file_obj);
                            }
                            else
                            {
                                file_obj.error = 'file not found'; // to set some errors codes
                                fn_end(file_obj);
                            }
                        };
                        c.onreadystatechange = function(e)
                        {
                            if(e.readyState == 4)
                            {
                                fn_end(file_obj);
                            }
                        };
                        c.ondatastream = function(e)
                        {
                            if ( fn_progress ) fn_progress(e.progress);
                        };
                        c.error = function(e)
                        {
                            file_obj.error = e.error;
                            fn_end(file_obj);
                            alert('Error with Download');
                        };
                        c.open('GET',url);
                        c.send();           
                    }
                    else
                    {
                        file_obj.error = 'no internet';
                        fn_end(file_obj);
                    }
                }
            };
        for (var d=0;d<items[c].prereqs.length;d++)
        {
    
    
    
            get_remote_file(
                items[c].prereqs[d].imagename,
                items[c].prereqs[d].imagesource,
                function(fileobj)
                {
                    Ti.API.info(fileobj);
                }, 
                function(progress)
                {
                    Ti.API.info(progress);
                }
            );
    
        }
    
    — answered November 2nd 2011 by P Sweeney
    permalink
    1 Comment
    • Ah ha.. I resolved this by simply setting the 'false' param to c.open:

      c.open('GET', url, false);
      

      Now all my downloads occur in order and async.

      — commented November 3rd 2011 by P Sweeney
  • I'm interested into this. I want to know how to download an image from a server and store it locally without using an imageView.

    — answered August 24th 2010 by Eneko Alonso
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.