Recentemente, tenho trabalhado no projeto phonegap/cordova. O principal objetivo do projeto era tirar fotos com a câmera do dispositivo e enviá-las para o servidor. É um projeto apache cordova usando o plugin camera. De acordo com a documentação, podemos enviar imagens com o seguinte código javascript:
navigator.camera.getPicture(onSuccess, onFail, { quality: 100, destinationType: Camera.DestinationType.DATA_URL }); function onSuccess(imageData) { // here we can upload imageData to the server } function onFail(message) { alert('Failed because: ' + message); }
Como podemos ver, nosso plugin devolve uma versão codificada em base64 de nossa imagem, e podemos enviá-la ao servidor utilizando o JQuery, por exemplo.
function onSuccess(imageData) { $.post( "upload.php", {data: imageData}, function(data) { alert("Image uploaded!"); }); }
O lado do servidor é trivial. Precisamos apenas ler a variável ‘data’ requisitada, realizar uma decodificação base64 e teremos a nossa imagem binária pronta para ser salva.
Testei com um smartphone Android antigo (com uma câmera não tão boa) e funciona, mas quando tentei usá-lo com um telefone Android melhor (com uma câmera de 8Mpx) ele ficou carregando e não funcionou. Depois de ler melhor a documentação, percebi que essa não é a melhor forma de enviar imagens para o servidor. Ela só funciona se a imagem é pequena. A base64 aumenta o tamanho da imagem e nosso dispositivo pode ter problemas para manipular a memória. Essa forma também é lenta como uma tartaruga.
A melhor maneira (aquela que funciona de fato) é, em vez de enviar imagens em base64 para o servidor, salvá-las dentro de uma pasta temporária no dispositivo e enviá-las usando o plugin de transferência de arquivos.
var pictureSource; // picture source var destinationType; // sets the format of returned value document.addEventListener("deviceready", onDeviceReady, false); function onDeviceReady() { pictureSource = navigator.camera.PictureSourceType; destinationType = navigator.camera.DestinationType; } function clearCache() { navigator.camera.cleanup(); } var retries = 0; function onCapturePhoto(fileURI) { var win = function (r) { clearCache(); retries = 0; alert('Done!'); } var fail = function (error) { if (retries == 0) { retries ++ setTimeout(function() { onCapturePhoto(fileURI) }, 1000) } else { retries = 0; clearCache(); alert('Ups. Something wrong happens!'); } } var options = new FileUploadOptions(); options.fileKey = "file"; options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1); options.mimeType = "image/jpeg"; options.params = {}; // if we need to send parameters to the server request var ft = new FileTransfer(); ft.upload(fileURI, encodeURI("http://host/upload"), win, fail, options); } function capturePhoto() { navigator.camera.getPicture(onCapturePhoto, onFail, { quality: 100, destinationType: destinationType.FILE_URI }); } function onFail(message) { alert('Failed because: ' + message); }
Eu percebi que às vezes isso falhava. Parece ser um bug no plugin do cordova (não tenho certeza); por causa disso, se você ler o meu código, pode ver que se pf.upload falhar eu tento novamente (apenas uma vez). Com esse pequeno truque, funciona que é uma beleza (e ainda é rápido).
A parte do servidor é bastante simples. Precisamos apenas manipular os arquivos enviados. Aqui está um exemplo minimalista em PHP:
<?php move_uploaded_file($_FILES["file"]["tmp_name"], '/path/to/file');
E é só. Podemos fazer facilmente o upload de nossas fotos de nossos smartphones usando phonegap/cordova.
***
Artigo traduzido pela Redação iMasters, com autorização do autor. Publicado originalmente em http://gonzalo123.com/2013/10/28/taking-photos-with-a-phonegapcordova-application-and-uploading-them-to-the-server/