Use NativeScript Plugin nativescript-background-http To Send And Store Camera Pictures On PHP Server

I searched and searched and asked on slack and asked on the NS FaceBook group and everything I could think of to figure this out.  I finally pieced it together and it’s working.  So do you want to let your app users take a picture with their camera, or use one in their library for something and you need that photo stored on your web server? We let users take before/progress/after pics from using our device.  We want to store these photos so we can see results ourselves and request use from our users for advertisements.  So here’s how you do it.

nativescript-background-http

You need to make sure and import your camera ui and also this plugin.  It’s extremely awesome and works great.  You can get it by running

tns plugin add nativescript-background-http

EDIT: For some reason when I put this on an actual device it wouldn’t save the photos.  When on the actual phone it has a problem with using knownFolders.currentApp() and a custom folder, so I change that line from

fs.knownFolders.currentApp().path + /saved_images;

to

fs.knownFolders.documents().path;

and it worked just fine.

After setting that up use the below code, or whatever parts of it you’d like, to make the NS function and push the upload to your server.  A couple notes though, I use a folder called /saved_images in my /app project directory to store the files before sending.  I’m not sure this is necessary but I wanted to resize to a maximum of 800px wide or height while retaining proportion.  It is extremely important this directory is created if you use this filepath or your script will fail and you won’t know why because error logging here doesn’t do anything.

Also, I store a global configuration variable for my api’s URL, so I use url: config.apiUrl in my request options.

https://gist.github.com/ChrisFlannagan/e9e32428935076419f24aec6a30a7381

Saving The Image In PHP

So the config.apiUrl points directly to my php file (ex:server.com/apifile.php).  In this file you need to access file_get_contents(‘php://input’) to access the streamed data coming in.  This is how you work with forms submitted using content type “application/octet-stream” to get the file data.  With this data you can simply save it however you’d like using file_put_contents.  There’s other security concerns you will need to address that I’m not going over here as they are different all different applications of this process.  But here’s a quick, simple line for saving the image to a /uploads/ directory:

$all_headers = apache_request_headers();
$newimg = file_put_contents('uploads/' . $all_headers['File-Name'], file_get_contents('php://input'));

Now your image has been saved!

Additional User Data Needed

If you are storing this image and attaching it to a user or any other kind of data you can pass these as header fields just as you did the File-Name.  In your JS just under the line:

"File-Name": filename

Add a comma and put the next field you might need such as:

"File-Name": filename,
"Email-Add": email

Enjoy!

9 thoughts on “Use NativeScript Plugin nativescript-background-http To Send And Store Camera Pictures On PHP Server”

  1. I was reading an article today about the new JPEG compression algorithm developed by Dropbox called Leptin which saves 22% losslessly. “It compresses JPEG files at a rate of 5 megabytes per second and decodes them back to the original bits at 15 megabytes per second, securely, deterministically, and in under 24 megabytes of memory.”

    It made me remember this article when I got to “Lepton is a fully streamable format, meaning the decompression can be applied to any file as that file is being transferred over the network. Hence, streaming overlaps the computational work of the decompression with the file transfer itself, hiding latency from the user.”

    That would be a huge boon for mobile image uploads from cameras, and a prime suspect for developing a NativeScript.js adapter that has the potential to be hugely popular as well as very performance enhancing to applications that use it.

    Best of all, Lepton is open source.

    https://github.com/dropbox/lepton

  2. Thanks for the awesome tutorial! I’m having a bit of a beginner’s problem, I’m afraid. Neither if(picsaved), nor it’s else statement, are being executed. The file on my server is also not being reached. Any idea why this would be? The rest of it works wonderfully.

    I’m basically wanting to be able to upload images from the camera, preferably accompanied by some other data, and/or in a predictable filename convention.

    Thanks in advance for any help you can provide.

    1. I should probably include my (slightly) altered code:

      var onTap = function (args) {
      console.log(“onTap.”); // this works
      cameraModule.requestPermissions();
      cameraModule.takePicture({width: 800, height: 800, keepAspectRatio: true}).then(function(picture) {
      var savepath = fs.knownFolders.currentApp().path + “/saved_images”; // tried this with and without the “/saved_images”
      var filename = ‘img_’ + new Date().getTime() + ‘.jpg’;
      var filepath = fs.path.join(savepath, filename);

      console.log(“file://” + filepath); // this works

      var picsaved = picture.saveToFile(filepath, enumsModule.ImageFormat.jpeg);
      if(picsaved) {
      console.log(“Saving”); //nothing in console
      var session = bghttp.session(“image-upload”);
      var request = {
      url: “http://192.168.1.54/experiments/nativescript/upload_test.php”,
      method: “POST”,
      headers: {
      “Content-Type”: “application/octet-stream”,
      “File-Name”: filename
      },
      description: “{ ‘uploading’: ‘” + filename + “‘ }”
      };

      console.log(“file://” + filepath);

      var task = session.uploadFile(“file://” + filepath, request);

      task.on(“progress”, logEvent);
      task.on(“error”, logEvent);
      task.on(“complete”, logEvent);
      function logEvent(e) {
      console.log(e.eventName); //nothing in console
      }
      } else {
      console.log(“Failed To Save”); //nothing in console
      }
      });
      };

      and yes, I’m on the safe network (server and android tablet).

  3. how to read “uploading” info from php ?
    I have tried Input::post(“uploading”); but it did not work
    I am using fuelphp for backend development

Leave a Reply

Your email address will not be published.