How to get the image binary by URL or name


#1

This is what I tried to do with my mobile app (built with Ionic, Angular, Cordova/Ngcordova) :

  • all the testing I’have done was on a real device (Samsung with Android 4.4.2)
  1. Add new images (I’m using cordova camera plugin)
  2. Copy the new image in my App folder (I used this demo http://devdactic.com/how-to-capture-and-store-images-with-ionic/)
  3. Save the images name in DB (I will use SQlite)(not done yet but doesn’t matter at the moment).
  4. Get the image path by name (for UI displaying and other UI operation)
  5. When an user has internet and he want he is able push a button to send all the added images to a server. (tried with ngcordova docs/plugins/file/)

Everythings is working except the point 5. I cannot get the image binary to be able to send it to the server.
I saw some others demo but everyone is using DATA_URL (instead FILE_URI - destinationType : Camera.DestinationType.FILE_URI,) to get the image in base64 and in the next step send it to the server.

I want to save all images; get them (from app folder)and send them when user want.

Is there any way to do this ? Is it posible in cordova ?

My code are below:

CONTROLLER:

'use strict';
angular.module('MyDemoApp.controllers')

.controller('SignupCtrl', function ($scope, $http,$cordovaFile, ImageService) {
 $scope.user = {};
 $scope.imgPath = '';
 $scope.imgName = '';
 $scope.addNewImage  = function (method){
	ImageService.addImage(method).then(function(data){    
	   $scope.user.image = data.src;
	   $scope.imgPath = data.imgObj;
	   $scope.imgName = data.name;

	   window.alert(JSON.stringify(data));
	   /* RESULTS : {"name":"aaaaaxxxxxxxxx.jpg",
					 "src":"file:///data/data/com.example.DemoApp/files/aaaaaxxxxxxxxx.jpg",
					 "imgObj":"file:///storage/emulated/0/Android/data/com.example.DemoApp/cache/xxxxxxxxx.jpg"
					}
				xxxxxxxxx.jpg - the original name of photo 
				aaaaaxxxxxxxxx.jpg - new generated name in service
		*/
	},function(err){
		window.alert('Add image error: ' + JSON.stringify(err));
	});  
}

$scope.signUp = function () {
		// V1            
		// This method is used to return a File object that represents the current state of the file represented by the FileEntry object. The parameters consist of two callback functions:
		//        successCallback- This is a callback that is called with a File object.
		//        errorCallback- This is a callback that is called if an error occurs when creating the File object (in other words, the underlying file no longer exists).
        function success(file) {
            window.alert("File type: " + file.type); // RESULT: image/jpeg
            window.alert("File size: " + file.size); // RESULT: 1191228
            window.alert(JSON.stringify(file));
		   /* RESULTS : {"name":"aaaaaxxxxxxxxx.jpg",
						 "localURL":"cdvfile://localhost/files/aaaaaxxxxxxxxx.jpg",
						 "type":"image/jpeg"
						 "lastModified":"some value "
						 "lastModifiedDate":"some value "
						 "size":"1191228",
						 "start":"0"
						 "end":"1191228"
						}
			*/				
        }
        function fail(error) { window.alert("Unable to retrieve file properties: " + error.code);}
        // obtain properties of a file
        entry.file(success, fail);      
    

		// $cordovaFile.readAsDataURL($scope.user.image, $scope.imgName)
		// $cordovaFile.readAsBinaryString($scope.user.image, $scope.imgName)
		$cordovaFile.readAsBinaryString(cordova.file.dataDirectory,$scope.imgName)
		.then(function (success) {
			window.alert(JSON.stringify(success))
			//NEVER GET HERE
			// success
		  }, function (error) {
			// error
			window.alert(JSON.stringify(error))
			// ALL THE TIME I GET ERROR CODE 5 OR 1000 OR 1 
		});  
}
});

MY SERVICE:

'use strict';
angular.module('MyDemoApp.services')
.service('ImageService', function($q, $cordovaCamera, $cordovaFile, $localStorage) {
  // 1    
   this.addImage = function (method){
        var deferred = $q.defer();
        var promise = deferred.promise;
        var imageDetails ={'name':'', 'src':'', 'imgObj':''};
        // 2
        // Set the "options array" [who is passed to the cordovaCamera] by method [take | choose]
        // Docs : http://plugins.cordova.io/#/package/org.apache.cordova.camera
        var options ={};
        if (method==='take'){
            options = {
              destinationType : Camera.DestinationType.FILE_URI,
              sourceType : Camera.PictureSourceType.CAMERA, 
              allowEdit : false,
              encodingType: Camera.EncodingType.JPEG,
              popoverOptions: CameraPopoverOptions,
            };
        } else if (method==='choose'){
            options = {
              destinationType : Camera.DestinationType.FILE_URI,
              sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
              allowEdit : false,
              encodingType: Camera.EncodingType.JPEG,
              popoverOptions: CameraPopoverOptions,
            };
        }
             
        // 3
        // Call the ngCodrova module cordovaCamera we injected to our service.
        $cordovaCamera.getPicture(options).then(function(imageData) {
                      // 4
                      // When the image capture returns data, we pass the information to our success function, 
                      // which will call some other functions to copy the original image to our app folder.
					  // window.alert(JSON.stringify(imageData));
                      onImageSuccess(imageData);

                      function onImageSuccess(fileURI) {
                        createFileEntry(fileURI);
                      }
                   
                      function createFileEntry(fileURI) {
                        imageDetails.imgObj=fileURI;
                        window.resolveLocalFileSystemURL(fileURI, copyFile, fail);
                      }
                   
                      // 5
                      // This function copies the original file to our app directory. 
                      // We have to deal with duplicate images, we give a new name to the file consisting of a random string and the original name of the image.
                      function copyFile(fileEntry) {
                        //var name = fileEntry.fullPath.substr(fileEntry.fullPath.lastIndexOf('/') + 1);
                        var name = fileEntry.nativeURL.substr(fileEntry.nativeURL.lastIndexOf('/') + 1);
                        var newName = makeid() + name;
                        window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(fileSystem2) {
                          fileEntry.copyTo(
                            fileSystem2,
                            newName,
                            onCopySuccess,
                            fail
                          );
                        },
                        fail);
                      }
                      
                      // 6
                      // If the copy task finishes successful, we push the image url to our scope array of images. 
                      // Make sure to use the apply() function to update the scope and view!
                      function onCopySuccess(entry) {
                        // entry = { 'isFile':'', 'isDirectory':'', 'Name':'', 'fullPath':'', 'fileSystem':'', 'NativeUrl':''}
                        imageDetails.name=entry.name;
                        imageDetails.src=entry.nativeURL;
                        deferred.resolve(imageDetails)                        
                      }
                   
                      function fail(error) { deferred.reject(error);}
                   
                      function makeid() { 
                        var text = '';
                        var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';                       
                        for (var i=0; i < 5; i++) {
                          text += possible.charAt(Math.floor(Math.random() * possible.length));
                        }
                        return text;
                      }                     
        }, function(err) {
          deferred.reject(err);
        }); 
    return deferred.promise
  }; // end addImage();


  this.urlForImage = function (imageName){
      // "urlForImage" function receive a param "imageName" and return the URL of image
      var trueOrigin='';
	  var name = imageName.substr(imageName.lastIndexOf('/') + 1);
	  trueOrigin = cordova.file.dataDirectory + name;
      return trueOrigin;    
  }; // end urlForImage()

  this.getImageObjByPath = function (imagePath){
	// Here I want to do something that return the image binary 
    return imageObject;
  };
});

I really appreciate any help

Thanks


#2

Damn, I was really hoping this one had an answer! I’m facing the same problem. Did you find a solution?
if so, please let me know.

-J


#3

So you have a DB with filenames and its locations.

Just convert each image to base64 string and then send the string with $http to your server.

On your server decode the base64 back to a file.

Then remove the filename on the device (db and physical file)


#4

Hi , I have the same problems like yours ,I have done everything except saving it to DB and push the images to a server .
can you please send me the full code example , I would really appreciate it .

Thanks


#5

Did you find an answer too ? :slight_smile: