Phonegap - 通过路径从相机胶卷中检索照片

发布于 2025-01-03 12:33:02 字数 1448 浏览 0 评论 0 原文

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

我将图像保存为数据库中的 Base64,但由于 PhoneGap API 文档

注意:使用较新相机拍摄的照片的图像质量 设备相当不错。使用 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);
}

In my PhoneGap/jQuery Mobile app, I'm currently using PhoneGaps' Camera API to allow the user to take a photo, which is also stored in the Camera Roll. I'm setting DestinationType to FILE_URI and saving this path in a local db. However, FILE_URI is a path to a temporary location that is destroyed when the app is closed. I was thinking of saving the name of the image and then retrieving the image from the Camera Roll. Is there a path I can use to later retrieve the images in the Camera Roll?

I was saving the images as Base64 in the db, but I'm a little weary of this method because of this note in the PhoneGap API Doc:

Note: The image quality of pictures taken using the camera on newer
devices is quite good. Encoding such images using Base64 has caused
memory issues on some of these devices (iPhone 4, BlackBerry Torch
9800). Therefore, using FILE_URI as the 'Camera.destinationType' is
highly recommended.

EDIT:

Got it working with @Simon MacDonald's answer. Here is my stripped-down code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心房敞 2025-01-10 12:33:02

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

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

After you retrieve the file using the FILE_URI method you should use the File API to copy the image from the temp folder to the Documents folder and store the new path in your DB.

So you would take the result of your getPicture() pass it to window.resolveLocalFileSystemURI() to get a FileEntry. Then you can call FileEntry.copyTo() method to back up your file.

盛装女皇 2025-01-10 12:33:02

从 Cordova 1.8 开始,此功能运行良好,请参阅:

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

As of Cordova 1.8 this is working well, see:

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

人生百味 2025-01-10 12:33:02

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

感谢西蒙的建议和凯西的解决方案。

我正在开发一个 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);
}

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

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 文件共享

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

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

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

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

Sorry that I had to create a separate post because I have not enough reputation to comment.

Thank you Simon for the advice and Casey for the solution.

I was working on a Cordova app that requires me to take a picture on iOS, save it in a directory and the link on local storage to be accessed later. After user submits the picture, the app needs to delete it from the directory.

Here are add on codes on how you can do that and also how you can view the project Documents folder.

You can get the full directory of the picture you want to delete by using $('#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);
}

Alternatively if you have a form with multiple photo attachments, you may want to give the Documents folder you created to store the photos a unique name. This way, you can delete the whole folder after you submit the batch of photos instead of deleting them one by one.

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

As for accessing the project Documents folder, you need to edit the plist to enable iTunes File Sharing

Go to [project_folder]/platforms/ios/[project_name]/[project_name]-Info.plist.
Right-click and open with XCode.

You will see a table of keys. Right-click anywhere below the table and Add Row. A new row will be created. Double-click on the key and type UIFileSharingEnabled. It will automatically change to Application supports iTunes file sharing, put that key value to YES.

Now if you go to iTunes under your iOS's device's applications, scroll all the way down to see the File Sharing area where you can see your folder. However, it is just there for you to 'Save to' but no editing.

Hope all these additional information helps. It took me 2 days of research to find out.

撕心裂肺的伤痛 2025-01-10 12:33:02

共享我的版本,该版本使用 Promise 和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 路径。

deferred = $q.defer();

需要改为:

deferred = jQuery.Deferred();

干杯

Sharing my version which uses promises and resolveLocalFileSystemURL except resolveLocalFileSystemURI because second one is deprecated. It also uses original file name in new created one.

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

Usage:

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

Multiple URIs usage:

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

New file URIs will be saved as "/photos/fileName.jpg".
To get the absolute path, you can use:

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

I'm using $q from angular here to handle promises but it can be easily changed to jQuery one.

deferred = $q.defer();

would need to be changed to:

deferred = jQuery.Deferred();

Cheers

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文