Capturing and storing a picture taken with the Camera into a local database / PhoneGap / Cordova / iOS
Asked Answered
V

5

14

I'm currently building an app for iOS using Phonegap/Cordova and jQuerymobile. The idea is to take photos with camera and store the captured image for future use. I would like to store the path/filename into my local database and to move the picture file to a persistent place in the iPhone.

Could someone provide me with an example ?

Vehicular answered 26/4, 2012 at 14:30 Comment(0)
V
35

Ok, here is the solution.

  • in the Html file

  • I have an image tag for displaying the picture taken by the camera :

  • I have a button that runs a function for taking photo : Capture Photo

  • The function to capture photo is (when the photo is taken, the scr of the 'smallImage' id is populated with the path of the photo)

    function capturePhoto() {
    // Take picture using device camera and retrieve image as base64-encoded string
        navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50 });
    }
    
    //Callback function when the picture has been successfully taken
    function onPhotoDataSuccess(imageData) {                
        // Get image handle
        var smallImage = document.getElementById('smallImage');
    
        // Unhide image elements
        smallImage.style.display = 'block';
        smallImage.src = imageData;
    }
    
    //Callback function when the picture has not been successfully taken
    function onFail(message) {
        alert('Failed to load picture because: ' + message);
    }
    
  • Now I want to move the picture in a permanent folder and then save the link into my database :

    function movePic(file){ 
        window.resolveLocalFileSystemURI(file, resolveOnSuccess, resOnError); 
    } 
    
    //Callback function when the file system uri has been resolved
    function resolveOnSuccess(entry){ 
        var d = new Date();
        var n = d.getTime();
        //new file name
        var newFileName = n + ".jpg";
        var myFolderApp = "EasyPacking";
    
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {      
        //The folder is created if doesn't exist
        fileSys.root.getDirectory( myFolderApp,
                        {create:true, exclusive: false},
                        function(directory) {
                            entry.moveTo(directory, newFileName,  successMove, resOnError);
                        },
                        resOnError);
                        },
        resOnError);
    }
    
    //Callback function when the file has been moved successfully - inserting the complete path
    function successMove(entry) {
        //I do my insert with "entry.fullPath" as for the path
    }
    
    function resOnError(error) {
        alert(error.code);
    }
    
  • My file has been saved in the database to display it, i put "file://" front of the row that contains the image src

Hope this help. J.

P.S. : - many thanks to Simon Mac Donald (http://hi.im/simonmacdonald) for his post on googledocs.

Vehicular answered 28/4, 2012 at 9:41 Comment(10)
Does this solution work for embedding images in a Microsoft Access Database?Neslund
@Jerome, can you provide me working example of this. I am on it but it is not working.Spathe
Where do you call this function movePic(file) ?Interdenominational
I can see that this indeed appears to work, but I can't seem to display a file properly. I set the image src to "file://" + entity.fullPath, but it does not appear to work. Is there some root I need to add as well?Audsley
the only thing that i don't uderstand is where you call the movePic functionCollinsworth
worried how movePic(file) function will work, let us know JeromeHyperbolic
You either call movePic(file) in your onPhotoDataSuccess() or on a button click somewhere. For those who were wondering.Duotone
How the same can be done while choosing image from the filesFortis
Saving entry.fullPath as image url in local storage and binding again in image doesn't work, it doesn't display imageFortis
I am able to display the image using the 'src' successfully so I'm sure it's stored somewhere, I just wasn't sure where it is. Does it use the device's storage capacity or as part of the app? Is there a size limitation?Crosstree
L
2

Jerome's answer works like a charm.. the only thing to point out to people when they want to use the file don't use entry.fullPath as this can sometimes cause issues, use entry.toURL() as this will give you the full path without having to add "file://" to the path as well as bypassing issues such as SD card storage..

Lignify answered 10/1, 2015 at 21:26 Comment(0)
T
1
if (index == '0')
{
    var options = {
        quality: 50,
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: Camera.PictureSourceType.CAMERA,
        allowEdit: false,
        encodingType: Camera.EncodingType.JPEG,
        popoverOptions: CameraPopoverOptions,
        saveToPhotoAlbum: false,
        correctOrientation:true
    };

    $cordovaCamera.getPicture(options).then(movePic,function(imageData) {
        $rootScope.imageUpload=imageData;
    }, function(err) {
        console.error(err);
    });

    function movePic(imageData){
        console.log("move pic");
        console.log(imageData);
        window.resolveLocalFileSystemURL(imageData, resolveOnSuccess, resOnError);
    }

    function resolveOnSuccess(entry){
        console.log("resolvetosuccess");

        //new file name
        var newFileName = itemID + ".jpg";
        var myFolderApp = "ImgFolder";

        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {
            console.log("folder create");

            //The folder is created if doesn't exist
            fileSys.root.getDirectory( myFolderApp,
                {create:true, exclusive: false},
                function(directory) {
                    console.log("move to file..");
                    entry.moveTo(directory, newFileName,  successMove, resOnError);
                    console.log("release");

                },
                resOnError);
        },
        resOnError);
    }

    function successMove(entry) {
        //I do my insert with "entry.fullPath" as for the path
        console.log("success");
        //this is file path, customize your path
        console.log(entry);
    }

    function resOnError(error) {
        console.log("failed");
    }

}
Tyne answered 20/10, 2015 at 5:39 Comment(3)
this coding working me, i declare itemID depent on my project, you can use new name in filename.jpgTyne
Saving entry.fullPath as image url in local storage and binding again in image doesn't work, it doesn't display imageFortis
@Pritish Above code is only working for single image selected, Instead of create temp array to select multiple images & push all in one clickTyne
R
0

I just did a that works with promises, based on Jérôme's answer above:

function moveFile(file){

    var deferred = $q.defer();

    window.resolveLocalFileSystemURL(file,
        function resolveOnSuccess(entry){

            var dateTime = moment.utc(new Date).format('YYYYMMDD_HHmmss');
            var newFileName = dateTime + ".jpg";
            var newDirectory = "photos";

            window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fileSys) {

                    //The folder is created if doesn't exist
                    fileSys.root.getDirectory( newDirectory,
                        {create:true, exclusive: false},
                        function(directory) {

                            entry.moveTo(directory, newFileName, function (entry) {
                                //Now we can use "entry.toURL()" for the img src
                                console.log(entry.toURL());
                                deferred.resolve(entry);

                            }, resOnError);
                        },
                        resOnError);
                },
                resOnError);
        }, resOnError);

    return deferred.promise;
}

function resOnError(error) {
    console.log('Awwww shnap!: ' + error.code);
}
Riccardo answered 17/8, 2017 at 16:26 Comment(1)
Nice implementation! I'd love to see this with a .done() .failed() .always() implementation. And, thanks for sharing!Soong
E
-3

There are 3 steps:

  1. Get the photo. Apple has a good example for this on the iPhone dev site
  2. Get your Documents directory, like so:
    
    NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(
                NSDocumentDirectory,
                NSUserDomainMask,
                YES);
    NSString *docDir = [arrayPaths objectAtIndex:0];
    
  3. And finally, storing the UIImage you got in step 1 out to disk:
    
    NSString *filename = @"mypic.png";
    NSString *fullpath = [docDir stringByAppendingPathComponent:filename];
    [UIImagePNGRepresentation(image) writeToFile:fullpath atomically:YES];
    
Endurable answered 26/4, 2012 at 14:41 Comment(1)
Many thanks for you answer, my post was not clear, I am using PhoneGap, not Objective C, I keep my question opened.Enesco

© 2022 - 2024 — McMap. All rights reserved.