Получить двоичное изображение по пути или имени на мобильном устройстве (приложение Ionic / Ng cordova)

Вот что я пытался сделать с моим мобильным приложением (созданным с помощью Ionic, Angular, Cordova/Ngcordova): * Все тесты, которые я проводил, были на реальном устройстве (Samsung с Android 4.4.2)

  1. Добавить новые изображения (я использую плагин Cordova Camera)
  2. Скопируйте новое изображение в папку моего приложения (я использовал эту демонстрацию http://devdactic.com/how-to-capture-and-store-images-with-ionic/)
  3. Сохраните название изображения в БД (я буду использовать SQlite)(пока не сделано, но сейчас это не имеет значения).
  4. Получить путь к изображению по имени (для отображения пользовательского интерфейса и других операций пользовательского интерфейса)
  5. Когда у пользователя есть Интернет, и он хочет, он может нажать кнопку, чтобы отправить все добавленные изображения на сервер. (пробовал с помощью ngcordova docs/plugins/file/)

Все работает, кроме пункта 5. Я не могу получить двоичный образ, чтобы иметь возможность отправить его на сервер. Я видел еще несколько демо, но все используют DATA_URL (вместо FILE_URI - destinationType: Camera.DestinationType.FILE_URI,), чтобы получить изображение в base64 и на следующем шаге отправить его на сервер.

Я хочу сохранить все изображения; получить их (из папки приложения) и отправить их, когда пользователь хочет.

Есть какой-либо способ сделать это? Это возможно в Кордове?

Мой код ниже:

ДИСПЕТЧЕР:

'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 
        });  
}
});

МОЙ СЕРВИС:

'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;
  };
});

Я очень ценю любую помощь

Спасибо

1 ответ

Решение

Привет Проблема в том, что плагин камеры хранит изображение в папке кеша, и вы пытаетесь получить к нему доступ, используя cordova.file.dataDirectory, поэтому cordova не может найти изображение.

Попробуйте прочитать из кэша или после использования плагина Camera для получения изображения, пожалуйста, скопируйте изображение в cordova.file.dataDirectory, а затем работайте оттуда. Сделайте так, чтобы ваше изображение было приватным, и вы сможете управлять им с помощью cordova.file.dataDirectory.

Надеюсь, поможет. Позвольте мне показать вам, что я сделал:

saveToFile: function(imageUrl) {

    return $q(function(resolve, reject) {
      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;
      }

      var name = imageUrl.substr(imageUrl.lastIndexOf('/') + 1);
      var namePath = imageUrl.substr(0, imageUrl.lastIndexOf('/') + 1);
      var newName = makeid() + name;

      $cordovaFile.copyFile(namePath, name, cordova.file.dataDirectory, newName)
        .then(function(info){
          resolve(newName);
        }, function(e){
          reject(e);
        });
    });
  },
Другие вопросы по тегам