2012-02-07 7 views
19

W mojej aplikacji PhoneGap/jQuery Mobile używam obecnie interfejsu API aparatu PhoneGaps, aby umożliwić użytkownikowi zrobienie zdjęcia, które jest również przechowywane w rolce z aparatu. Ustawiam DestinationType na FILE_URI i zapisuję tę ścieżkę w lokalnej bazie danych. Jednak FILE_URI to ścieżka do tymczasowej lokalizacji, która jest niszczona po zamknięciu aplikacji. Myślałem o zapisaniu nazwy obrazu, a następnie odzyskaniu obrazu z rolki kamery. Czy istnieje ścieżka, z której mogę później pobrać obrazy z rolki z aparatu?Phonegap - pobieranie zdjęcia z rolki aparatu po ścieżce

byłem zapisywania obrazów jako base64 w db, ale jestem trochę zmęczony tej metody z powodu tej noty w PhoneGap API Doc:

Uwaga: Jakość obrazu zdjęć wykonanych za pomocą aparatu na nowszych urządzeniach jest całkiem niezły. Kodowanie takich obrazów za pomocą Base64 spowodowało problemy z pamięcią na niektórych urządzeniach (iPhone 4, BlackBerry Torch 9800). Dlatego zalecane jest użycie parametru FILE_URI jako "Camera.destinationType".

EDIT:

Got to praca z odpowiedzią @Simon MacDonalda. Oto mój kod okrojoną:

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

staram się obsługiwać ten dokładnie tę samą sytuację, a pisał kod wydaje się działać i otrzymuję całą drogę do twoja funkcja onCopySuccess, ale nadal nie widzę żadnych zdjęć w Rolce z aparatu ani w żadnym innym albumie. Wpis otrzymany w funkcji onCopySuccess opisuje plik, który zostanie wyczyszczony po wyczyszczeniu tymczasowej. - Yoh Suzuki właśnie teraz edytuj –

+1

Powyższy kod nie zapisze zdjęcia w albumie, tylko w folderze Dokumenty w aplikacji. Ścieżka do zdjęcia będzie wyglądać mniej więcej tak: '" /var/mobile/Applications/017323CA-35C1-4D50-9CBA-DCC7C697FAF1/Documents/photos/file.jpg " '. Dowolny ciąg to folder utworzony przez iOS dla Twojej aplikacji. Aby zapisać zdjęcie do rolki aparatu, w wywołaniu getPicture dodaj to do obiektu opcji: '" savePhotoToAlbum ":" true "'. Pamiętaj, że ścieżki obrazu nie można uzyskać w rolce z aparatu (AFAIK), dlatego musisz zapisać kopię w folderze Dokumenty w aplikacji. – Casey

+0

savePhotoToAlbum nie działa dla mnie i nie ma go w dokumentacji. –

Odpowiedz

10

Po pobraniu pliku za pomocą metody FILE_URI należy użyć File API, aby skopiować obraz z folderu temp do folderu dokumenty i zapisać nową ścieżkę w DB .

Więc możesz wziąć wynik swojego getPicture() przekazać go do window.resolveLocalFileSystemURI(), aby uzyskać FileEntry. Następnie możesz wywołać metodę FileEntry.copyTo(), aby utworzyć kopię zapasową pliku.

+1

Dzięki. Jak na razie dobrze. Mam problem z utworzeniem katalogu, do którego można skopiować zdjęcie, ponieważ nie jestem pewien, co określić jako parametr fullPath podczas tworzenia instancji DirectoryEntry. Przykładowy wygląd dokumentu dostał rodzic od nadrzędnego dokumentu HTML, ale nie patrzę na to zbytnio. Czy wiesz, co należy określić jako parametr fullPath? – Casey

+0

Nieważne, wymyśliłem to. Dzięki. Czy opublikować kod tutaj za sekundę. – Casey

+0

Simon Nie sądzę, że masz przykład kodu, jak to osiągnąć, prawda? – pleshy

0

Przepraszam, że musiałem utworzyć osobne stanowisko, ponieważ nie mam wystarczająco dużo reputacji uwag.

Dziękuję Simonowi za poradę i Casey za rozwiązanie.

Pracowałem nad aplikacją Cordova, która wymaga ode mnie zrobienia zdjęcia na iOS, zapisania go w katalogu i łącza do lokalnej pamięci masowej, aby uzyskać do niego dostęp później. Po przesłaniu zdjęcia aplikacja musi usunąć ją z katalogu.

Oto kody, jak to zrobić, a także w jaki sposób można wyświetlić folder Dokumenty projektu.

Możesz uzyskać pełny katalog zdjęcia, które chcesz usunąć, używając $ ('# 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); 
} 

Ewentualnie, jeśli masz formularz z wieloma załącznikami fotograficznych, może chcesz dać Dokumenty folder utworzony w celu umieścić obrazy unikalną nazwę. W ten sposób możesz usunąć cały folder po przesłaniu partii zdjęć, zamiast usuwać je jeden po drugim.

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

W celu uzyskania dostępu do folderu projektu dokumenty, trzeba edytować plist włączyć iTunes File Sharing

Przejdź do [project_folder]/platform/iOS/[PROJECT_NAME]/[PROJECT_NAME] -Info.plist. Kliknij prawym przyciskiem myszy i otwórz przy pomocy XCode.

Zobaczysz tabelę kluczy. Kliknij prawym przyciskiem myszy wszędzie pod tabelą i Dodaj wiersz. Zostanie utworzony nowy wiersz. Kliknij dwukrotnie klucz i wpisz: UIFileSharingEnabled. Automatycznie zmieni się na Aplikacja obsługuje udostępnianie plików iTunes, wpisz tę wartość klucza na TAK.

Teraz, jeśli przejdziesz do iTunes w aplikacjach na urządzenia z systemem iOS, przewiń do samego dołu, aby zobaczyć obszar Udostępnianie plików, w którym możesz zobaczyć swój folder. Jest jednak po to, abyś zapisał, ale nie edytował.

Mam nadzieję, że wszystkie te dodatkowe informacje pomagają. Badanie zajęło mi 2 dni.

0

Udostępnianie mojej wersji, która używa obietnic i resolveLocalFileSystemURL z wyjątkiem resolveLocalFileSystemURI, ponieważ druga jest nieaktualna. Używa również oryginalnej nazwy pliku w nowej utworzonej.

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

Zastosowanie:

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

Wielokrotne użycie 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); 
}); 

Nowe URI plik zostanie zapisany jako "/photos/fileName.jpg". Aby uzyskać bezwzględną ścieżkę, można użyć:

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

Używam $ q od kanciasty, żeby obsłużyć obietnic, ale może być łatwo zmieniona na jednym jQuery.

deferred = $q.defer(); 

musiałyby zostać zmienione na:

deferred = jQuery.Deferred(); 

Cheers