【问题标题】:Phonegap - Retrieve photo from Camera Roll via pathPhonegap - 通过路径从相机胶卷中检索照片
【发布时间】:2012-02-29 03:28:56
【问题描述】:

在我的PhoneGap/jQuery Mobile 应用程序中,我目前正在使用PhoneGaps 的相机API 来允许用户拍照,该照片也存储在相机胶卷中。我将 DestinationType 设置为 FILE_URI 并将此路径保存在本地数据库中。但是,FILE_URI 是一个临时位置的路径,在应用程序关闭时会被销毁。我正在考虑保存图像的名称,然后从相机胶卷中检索图像。是否有路径可供我稍后检索相机胶卷中的图像?

我在数据库中将图像保存为 Base64,但由于PhoneGap API Doc 中的此注释,我对这种方法有点厌倦:

注意:使用较新的相机拍摄的照片的图像质量 设备相当不错。使用 Base64 编码此类图像会导致 其中一些设备(iPhone 4、BlackBerry Torch)上的内存问题 9800)。因此,使用 FILE_URI 作为 'Camera.destinationType' 是 强烈推荐。

编辑:

得到它与@Simon MacDonald 的回答一起工作。这是我的精简代码:

function capturePhoto() {
    navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 25, destinationType: Camera.DestinationType.FILE_URI });
}

function onPhotoURISuccess(imageURI) {
    createFileEntry(imageURI);
}

function createFileEntry(imageURI) {
    window.resolveLocalFileSystemURI(imageURI, copyPhoto, fail);    
}

function copyPhoto(fileEntry) {
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) { 
        fileSys.root.getDirectory("photos", {create: true, exclusive: false}, function(dir) { 
                fileEntry.copyTo(dir, "file.jpg", onCopySuccess, fail); 
            }, fail); 
    }, fail); 
}

function onCopySuccess(entry) {
    console.log(entry.fullPath)
}

function fail(error) {
    console.log(error.code);
}

【问题讨论】:

  • 我正在尝试处理这种完全相同的情况,并且您发布的代码似乎可以正常工作,并且我一直使用您的 onCopySuccess 函数,但我的相机胶卷或任何其他内容中仍然看不到任何图像专辑。我在 onCopySuccess 函数中获得的条目描述了一个在 temp 被清除时被清除的文件。 – Yoh Suzuki 刚刚编辑
  • 以上代码不会将照片保存到相册,而是保存到应用的 Documents 文件夹中。照片的路径如下所示:"/var/mobile/Applications/017323CA-35C1-4D50-9CBA-DCC7C697FAF1/Documents/photos/file.jpg" 。任意字符串是 iOS 为您的应用创建的文件夹。要将照片保存到相机胶卷,请在 getPicture 调用中将其添加到选项对象:"savePhotoToAlbum" : "true"。请注意,您无法在相机胶卷 (AFAIK) 中获取图像的路径,这就是您必须将副本保存到应用程序的 Documents 文件夹的原因。
  • savePhotoToAlbum 似乎对我不起作用,并且不在文档中。
  • 啊,我明白了。它实际上是“saveToPhotoAlbum”。这行得通!
  • 抱歉打错了。感谢您的修复。是的,不知道为什么它不在文档中。我忘记了在哪里找到它,但他们认为它不在文档中,因为它特定于 iOS;这对我来说似乎不是一个很好的理由。

标签: cordova photo


【解决方案1】:

使用 FILE_URI 方法检索文件后,您应该使用 File API 将图像从 temp 文件夹复制到 Documents 文件夹并将新路径存储在您的数据库中。

因此,您可以将 getPicture() 的结果传递给 window.resolveLocalFileSystemURI() 以获取 FileEntry。然后你可以调用FileEntry.copyTo()方法来备份你的文件。

【讨论】:

  • 谢谢。到目前为止,一切都很好。我在创建将照片复制到的目录时遇到问题,因为我不确定在创建 DirectoryEntry 实例时要指定什么作为 fullPath 参数。 doc 示例看起来从 HTML 文档的父级获得了父级,但我对此并没有太多了解。你知道应该指定什么作为 fullPath 参数吗?
  • 没关系,想通了。谢谢。稍后将在此处发布代码。
  • Simon 我不认为你已经有一些示例代码来说明如何实现这一点吗?
【解决方案2】:

从 Cordova 1.8 开始,这运行良好,请参阅:

http://docs.phonegap.com/en/1.8.0/cordova_camera_camera.md.html#Camera

【讨论】:

    【解决方案3】:

    很抱歉,我不得不创建一个单独的帖子,因为我没有足够的声誉来发表评论。

    感谢 Simon 的建议和 Casey 的解决方案。

    我正在开发一个 Cordova 应用程序,该应用程序需要我在 iOS 上拍照,将其保存在目录中,并将链接保存在本地存储中以供以后访问。用户提交图片后,应用需要将图片从目录中删除。

    这里是有关如何执行此操作以及如何查看项目文档文件夹的附加代码。

    你可以通过$('#pictureid').attr('src')获取你要删除的图片的完整目录。

    function deletePic(file){
        console.log("deleting: "+file+"...");
        var file = "photos/"+file.toString().split('/').slice(-1)[0]; //gets photo name
    
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys){
        fileSys.root.getFile(file, 
                    {create:false}, 
                    function(entry){
                        entry.remove();
                    }, resOnErrorDelete);
                    },
        resOnErrorDelete);          
    }
    
    function resOnErrorDelete(error) {
        console.log("resOnErrorDelete: "+error.code);
    }
    

    或者,如果您有一个包含多个照片附件的表单,您可能希望为您创建的用于存储照片的 Documents 文件夹指定一个唯一的名称。这样一来,您可以在提交一批照片后删除整个文件夹,而不是一张一张地删除。

    function deleteFolder(folder){  
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys){
        fileSys.root.getDirectory(folder, 
                    {create:true, exclusive: false}, 
                    function(entry){
                        entry.removeRecursively();
                    }, resOnErrorDelete);
                    },
        resOnErrorDelete);          
    }
    
    function resOnErrorDelete(error) {
        console.log("resOnErrorDelete: "+error.code);
    }
    

    至于访问项目Documents文件夹,需要编辑plist启用iTunes File Sharing

    转到 [project_folder]/platforms/ios/[project_name]/[project_name]-Info.plist。 右键单击并使用 XCode 打开。

    您将看到一个键表。右键单击表格下方的任意位置并添加行。将创建一个新行。双击该键并键入 UIFileSharingEnabled。它将自动更改为应用程序支持iTunes文件共享,将该键值设置为YES

    现在,如果您在 iOS 设备的应用程序下访问 iTunes,请一直向下滚动以查看文件共享区域,您可以在其中看到您的文件夹。但是,它只是供您“保存到”而不是编辑。

    希望所有这些附加信息对您有所帮助。我花了 2 天时间研究才找到答案。

    【讨论】:

      【解决方案4】:

      分享我使用 promises 和 resolveLocalFileSystemURL 的版本,但 resolveLocalFileSystemURI 除外,因为第二个版本已弃用。它还在新创建的文件中使用原始文件名。

      function copyPhotoToAppDir(imageURI) {
        if(!imageURI){
          console.warn("You need to pass imageURI");
          return;
        }
      
        var fileNameSplit = imageURI.split("/"),
          fileName = fileNameSplit[fileNameSplit.length - 1],
          deferred = $q.defer();
      
        var copyPhoto = function(fileEntry) {
          window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
            fileSys.root.getDirectory("photos", {create: true, exclusive: false}, function(dir) {
              fileEntry.copyTo(dir, fileName, onCopySuccess, onFileFail);
            }, onFileFail);
          }, onFileFail);
        };
      
        var onCopySuccess = function onCopySuccess(entry) {
          console.log("NEW PATH", entry.fullPath);
          deferred.resolve(entry.fullPath);
        };
      
        var onFileFail = function (error) {
          console.log("COPY FAIL", error);
          deferred.reject();
        };
      
        window.resolveLocalFileSystemURL(imageURI, copyPhoto, onFileFail);
      
        return deferred.promise;
      }
      

      用法:

      var uri = "path1";
      copyPhotoToAppDir(uri).then(function(newURI){
        console.log(newURI);
      });
      

      多个 URI 用法:

      var uriArr = ["path1", "path2"]; 
        copyPhotoPromises = [];
      
      uriArr.forEach(function(val){
        copyPhotoPromises.push(copyPhotoToAppDir(val));
      });
      $q.all(copyPhotoPromises).then(function(values){
        console.log("Array with new paths", values);
      });
      

      新文件 URI 将保存为“/photos/fileName.jpg”。 要获取绝对路径,可以使用:

      cordova.file.documentsDirectory + newFileUri.substring(1);
      

      我在这里使用 Angular 中的 $q 来处理 Promise,但它可以很容易地更改为 jQuery one。

      deferred = $q.defer();
      

      需要改成:

      deferred = jQuery.Deferred();
      

      干杯

      【讨论】:

        猜你喜欢
        • 2012-11-04
        • 1970-01-01
        • 2012-07-22
        • 1970-01-01
        • 2013-04-03
        • 2011-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多