在移动设备上通过路径或名称获取二进制图像(Ionic / Ng cordova 应用程序)

get binary image by path or name on mobile (Ionic / Ng cordova app)

这是我尝试使用我的移动应用程序(使用 Ionic、Angular、Cordova/Ngcordova)进行的操作: * 我所做的所有测试都是在真实设备上进行的(三星 Android 4.4.2)

  1. 添加新图像(我使用的是 cordova 相机插件)
  2. 将新图片复制到我的App文件夹中(我用的是这个demohttp://devdactic.com/how-to-capture-and-store-images-with-ionic/
  3. 将图片名称保存到数据库中(我会使用SQlite)(还没有完成,但暂时无所谓)。
  4. 通过名称获取图片路径(用于UI显示和其他UI操作)
  5. 当用户有互联网并且他希望他能够按下按钮将所有添加的图像发送到服务器。 (尝试使用 ngcordova docs/plugins/file/)

除第 5 点外一切正常。我无法获取图像二进制文件以将其发送到服务器。 我看到了其他一些演示,但每个人都在使用 DATA_URL(而不是 FILE_URI - destinationType : Camera.DestinationType.FILE_URI)来获取 base64 中的图像,并在下一步中将其发送到服务器。

我要保存所有图片;获取它们(从应用程序文件夹)并在用户需要时发送它们。

有什么办法吗?在 cordova 中可行吗?

我的代码如下:

控制器:

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

非常感谢任何帮助

谢谢

您好问题是相机插件将图像存储在缓存文件夹中,而您正在尝试使用 cordova.file.dataDirectory 访问图像,这就是 cordova 找不到图像的原因。

尝试从缓存中读取或使用相机插件拍摄图像后,请将图像复制到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);
        });
    });
  },