Phonegap - Retrieve photo from Camera Roll via path

限于喜欢 提交于 2019-12-18 11:47:47

问题


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

回答1:


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.




回答2:


As of Cordova 1.8 this is working well, see:

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




回答3:


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.




回答4:


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



来源:https://stackoverflow.com/questions/9180731/phonegap-retrieve-photo-from-camera-roll-via-path

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!