cordova - picture - Phonegap-Recupera una foto de Camera Roll a través de una ruta
plugin name cordova plugin camera (4)
A partir de Córdoba 1.8 esto está funcionando bien, ver:
http://docs.phonegap.com/en/1.8.0/cordova_camera_camera.md.html#Camera
En mi aplicación PhoneGap / jQuery Mobile, actualmente estoy usando la API de la cámara de PhoneGaps para permitirle al usuario tomar una foto, que también está almacenada en el rollo de la cámara. Estoy configurando DestinationType en FILE_URI y guardando esta ruta en una base de datos local. Sin embargo, FILE_URI es una ruta a una ubicación temporal que se destruye cuando se cierra la aplicación. Estaba pensando en guardar el nombre de la imagen y luego recuperar la imagen del rollo de la cámara. ¿Hay algún camino que pueda usar para recuperar luego las imágenes en el rollo de la cámara?
Estaba guardando las imágenes como Base64 en la base de datos, pero estoy un poco cansado de este método debido a esta nota en el documento de la API de PhoneGap :
Nota: la calidad de imagen de las imágenes tomadas con la cámara en dispositivos más nuevos es bastante buena. La codificación de estas imágenes con Base64 ha causado problemas de memoria en algunos de estos dispositivos (iPhone 4, BlackBerry Torch 9800). Por lo tanto, se recomienda utilizar FILE_URI como ''Camera.destinationType''.
EDITAR:
Lo tengo trabajando con la respuesta de @Simon MacDonald. Aquí está mi código simplificado:
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);
}
Compartir mi versión que utiliza promises y resolverLocalFileSystemURL, excepto resolverLocalFileSystemURI porque el segundo está en desuso. También utiliza el nombre del archivo original en uno nuevo creado.
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;
}
Uso:
var uri = "path1";
copyPhotoToAppDir(uri).then(function(newURI){
console.log(newURI);
});
Uso de múltiples URIs:
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);
});
Los archivos URI nuevos se guardarán como "/photos/fileName.jpg". Para obtener la ruta absoluta, puede utilizar:
cordova.file.documentsDirectory + newFileUri.substring(1);
Estoy usando $ q de angular aquí para manejar promesas pero se puede cambiar fácilmente a jQuery one.
deferred = $q.defer();
necesitaría ser cambiado a:
deferred = jQuery.Deferred();
Aclamaciones
Después de recuperar el archivo utilizando el método FILE_URI, debe usar la API de archivos para copiar la imagen de la carpeta temporal a la carpeta Documentos y almacenar la nueva ruta en su base de datos.
Así que tomaría el resultado de su getPicture () páselo a window.resolveLocalFileSystemURI() para obtener un FileEntry. Luego puede llamar al método FileEntry.copyTo() para hacer una copia de seguridad de su archivo.
Lo siento, tuve que crear una publicación separada porque no tengo suficiente reputación para comentar.
Gracias Simon por el consejo y Casey por la solución.
Estaba trabajando en una aplicación de Cordova que me obliga a tomar una foto en iOS, guardarla en un directorio y acceder al enlace en el almacenamiento local más adelante. Una vez que el usuario envía la imagen, la aplicación debe eliminarla del directorio.
Aquí se agregan códigos sobre cómo puede hacer eso y también cómo puede ver la carpeta Documentos del proyecto.
Puede obtener el directorio completo de la imagen que desea eliminar usando $ (''# 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);
}
Alternativamente, si tiene un formulario con varios archivos adjuntos de fotos, es posible que desee asignar un nombre único a la carpeta Documentos que creó para almacenar las fotos. De esta manera, puede eliminar toda la carpeta después de enviar el lote de fotos en lugar de eliminarlas una por una.
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);
}
En cuanto al acceso a la carpeta Documentos del proyecto, debe editar la lista para habilitar el uso compartido de archivos de iTunes
Vaya a [project_folder] / platform / ios / [project_name] / [project_name] -Info.plist . Haz clic derecho y abre con XCode.
Verás una tabla de llaves. Haga clic derecho en cualquier lugar debajo de la tabla y Agregar fila. Se creará una nueva fila. Haga doble clic en la clave y escriba UIFileSharingEnabled . Cambiará automáticamente a Aplicación compatible con el uso compartido de archivos de iTunes , ponga ese valor clave en SÍ .
Ahora, si va a iTunes en las aplicaciones de su dispositivo iOS, desplácese hacia abajo para ver el área de uso compartido de archivos donde puede ver su carpeta. Sin embargo, solo está ahí para que ''Guardar en'', pero sin edición.
Espero que toda esta información adicional ayude. Me tomó 2 días de investigación para averiguarlo.