Accessing Image Gallery using Ionic and ngCordova

Written by on August 27, 2015

Accessing Image Gallery using Ionic and ngCordova

I wrote this article to show you how to access your smartphone image gallery. Attached to this article will be a working example you can reuse for your needs.

Note: If this tutorial was helpful, you need further clarification, something is not working or you have a request for another Ionic post? Furthermore, leave me a comment below if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com. Thanks and have a nice day!

Preparation

If you don’t have a preset development environment then make sure you have these:

  • Android Environment (or iOS if your working on a MacOS)
  • nodeJS
  • Ionic
  • Cordova

No previous Ionic Framework experience, find more information here: Ionic Framework | Installation Guide.

1. Update Ionic & Cordova

This tutorial requires the latest possible nodeJs version you can use. You will not be able to download/update latest Ionic Framework or Cordova without it.

Now we can update Ionic, and Cordova. Just be warned, older versions may not work with this tutorial:

npm update -g cordova ionic

2. Create a New Project

ionic start IonicImagePickerDemo blank
cd IonicImagePickerDemo
Warning: Since some of you never worked with Ionic CLI. From this point and further, every time I tell you to execute something, do that inside a project folder.

This example requires Android platform:

ionic platform add android

For MacOS users, do it like this:

ionic platform add ios

3. Download ngCordova archive

ngCordova is a collection of 63+ AngularJS extensions on top of the Cordova API that make it easy to build, test, and deploy Cordova mobile apps with AngularJS. While we can make this work without ngCordova, it’s much more practical this way. This collection also holds many Ionic Framework compatible plugins.

Download ngCordova zip file, here’s site link:

Official Site
Docs
Download Link

Unzip this archive, find a file name called: ng-cordova.min.js, it should be available at this location: ng-cordova-master\dist\.

Open your newly created project directory and copy ng-cordova.min.js to this location: IonicImagePickerDemo\www\js.

Now include this location to index.html located at IonicImagePickerDemo\www; add it above cordova.js file, like this:

<!-- cordova script (this will be a 404 during development) -->
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>

4. Install Cordova Image Picker Plugin

Add required plugins:

cordova plugin add https://github.com/wymsee/cordova-imagePicker.git
cordova plugin add cordova-plugin-whitelist
cordova plugin add org.apache.cordova.contacts
cordova plugin add https://github.com/hazemhagrass/phonegap-base64 

Install Whitelist plugin only if you’re using Cordova 4.0 +. Without it you’ll receive “Application Error: There was a network error.” error.
On the other hand, add last two plugins only if you’re intending to reuse my example. They’re not required for Image Picker.

GitHub - Image Picker

Development

At this point, you should have everything set up and ready, we can start working on our example.

Go to IonicImagePickerDemo project directory and find app.js, alter angular.module line and include ngCordova service, like this:

var app = angular.module('starter', ['ionic', 'ngCordova'])

Open index.html file, add a controller to ion-pane directive:

  <ion-pane>
      <ion-header-bar class="bar-stable">
        <h1 class="title">Image Picker Example</h1>
      </ion-header-bar>
      <ion-content ng-controller="ImagePickerController">
      </ion-content>
   </ion-pane>

Initialize this controller in app.js file; don’t forget to inject $cordovaImagePicker service. We will also need $ionicPlatform, like this:

app.controller('ImagePickerController', function($scope, $cordovaImagePicker, $ionicPlatform) {

});

If you’re using Cordova 4+ you will need to check if there’s a Whitelist plugin installed with your project. If you have it, add this security meta tag to your index.html HEAD content:

<meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src  'self' 'unsafe-inline' *">

Without it your application will throw an error during the app initialization, after that it will constantly throwing no security meta-tag found. While not a blocking point, constant console log warnings will make it hard to do any debugging.

We will use next function to trigger a notification, don’t forget to wrap it into Cordova deviceready event (or Ionic ready event depending on your project):

$scope.getImageSaveContact = function() {		
        // Image picker will load images according to these settings
	var options = {
		maximumImagesCount: 1, // Max number of selected images, I'm using only one for this example
		width: 800,
		height: 800,
		quality: 80            // Higher is better
	};

	$cordovaImagePicker.getPictures(options).then(function (results) {
                // Loop through acquired images
		for (var i = 0; i < results.length; i++) {
			console.log('Image URI: ' + results[i]);   // Print image URI
		}
	}, function(error) {
		console.log('Error: ' + JSON.stringify(error));    // In case of error
	});
};	

id is the most important part of this function. It’s a number that represents your local notification. Once you trigger it you can update it or cancel it through this number. In the next example, you’ll find all necessary examples.

Example

We will create an example that will load an image from that smartphone gallery and add it to a newly created contact.

This is what our application looks like:

HTML

Application main page.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="Content-Security-Policy" content="default-src *; script-src 'self' 'unsafe-inline' 'unsafe-eval' *; style-src  'self' 'unsafe-inline' *"/>
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"/>
        <title></title>

        <link href="lib/ionic/css/ionic.css" rel="stylesheet"/>
        <link href="css/style.css" rel="stylesheet"/>

        <!-- ionic/angularjs js -->
        <script src="lib/ionic/js/ionic.bundle.js"></script>

        <!-- cordova script (this will be a 404 during development) -->
        <script src="js/ng-cordova.min.js"></script>    
        <script src="cordova.js"></script>

        <!-- your app's js -->
        <script src="js/app.js"></script>
    </head>
    <body ng-app="starter">

        <ion-pane>
            <ion-header-bar class="bar-stable">
                <h1 class="title">Image Picker Example</h1>
            </ion-header-bar>
            <ion-content ng-controller="ImagePickerController">
                <button class="button button-full button-positive" ng-click="getImageSaveContact()">
                    Get Image and Save a Contact with It
                </button>
                <img ng-src="{{collection.selectedImage}}" style="width:100%; height: auto;"/>
            </ion-content>
        </ion-pane>

    </body>
</html>

JavaScript

Application JavaScript file.

var app = angular.module('starter', ['ionic','ngCordova']);

app.run(function($ionicPlatform) {
    $ionicPlatform.ready(function() {
        // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
        // for form inputs)
        if(window.cordova && window.cordova.plugins.Keyboard) {
            cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
        }
        if(window.StatusBar) {
            StatusBar.styleDefault();
        }
    });
});

app.controller('ImagePickerController', function($scope, $cordovaImagePicker, $ionicPlatform, $cordovaContacts) {

    $scope.collection = {
        selectedImage : ''
    };

    $ionicPlatform.ready(function() {

        $scope.getImageSaveContact = function() {		
            // Image picker will load images according to these settings
            var options = {
                maximumImagesCount: 1, // Max number of selected images, I'm using only one for this example
                width: 800,
                height: 800,
                quality: 80            // Higher is better
            };

            $cordovaImagePicker.getPictures(options).then(function (results) {
                // Loop through acquired images
                for (var i = 0; i < results.length; i++) {
                    $scope.collection.selectedImage = results[i];   // We loading only one image so we can use it like this

                    window.plugins.Base64.encodeFile($scope.collection.selectedImage, function(base64){  // Encode URI to Base64 needed for contacts plugin
                        $scope.collection.selectedImage = base64;
                        $scope.addContact();    // Save contact
                    });
                }
            }, function(error) {
                console.log('Error: ' + JSON.stringify(error));    // In case of error
            });
        };	

    });	

    $scope.contact = {     // We will use it to save a contact

        "displayName": "Gajotres",
        "name": {
            "givenName"  : "Dragannn",
            "familyName" : "Gaiccc",
            "formatted"  : "Dragannn Gaiccc"
        },
        "nickname": 'Gajotres',
        "phoneNumbers": [
            {
                "value": "+385959052082",
                "type": "mobile"
            },
            {
                "value": "+385914600731",
                "type": "phone"
            }				
        ],
        "emails": [
            {
                "value": "dragan.gaic@gmail.com",
                "type": "home"
            }
        ],
        "addresses": [
            {
                "type": "home",
                "formatted": "Some Address",
                "streetAddress": "Some Address",
                "locality":"Zagreb",
                "region":"Zagreb",
                "postalCode":"10000",
                "country":"Croatia"
            }
        ],
        "ims": null,
        "organizations": [
            {
                "type": "Company",
                "name": "Generali",
                "department": "IT",
                "title":"Senior Java Developer"
            }
        ],
        "birthday": Date("08/01/1980"),
        "note": "",
        "photos": [
            {
                "type": "base64",
                "value": $scope.collection.selectedImage

            }
        ],
        "categories": null,
        "urls": null
    }			

    $scope.addContact = function() {
        $cordovaContacts.save($scope.contact).then(function(result) {
            console.log('Contact Saved!');
        }, function(err) {
            console.log('An error has occured while saving contact data!');
        });
    };	

});

Deployment

Next step, we need to build our application:

ionic build android

Be careful here, this step may break if you’re behind a firewall. The first execution will take a long time, so be patient.

When this step ends, look at the output log, last two lines should look something like this:

Built the following apk(s):
    D:\Development\IonicImagePickerDemo\platforms\android\build\outputs\apk\android-debug.apk

We’ll use the last line location to deploy our application. Make sure your smartphone is prepared to accept an incoming application. In case of Android platform, you must enable Developer Options and USB Debugging.

Do this:

adb install -r platforms\android\build\outputs\apk\android-debug.apk

or you can do this:

ionic run android -l -c -s
Categories

38 thoughts on “Accessing Image Gallery using Ionic and ngCordova”

  1. thx for your this post! And I want to show the image that anyone i selected on some view. now,i can get the results data like this( file:///data/data/com.ionicframework.ioncus549345/cache/xxxx.jpg).However, it don’t appear as excepted when i use this image file path. How should I do?

  2. Hi.. where can i get the download link for this sample ? I am not able to find the attachment. could you please guide me to that.

      • I’m getting an error as follows:

        ionic.bundle.js:26794 TypeError: Cannot read property ‘getPictures’ of undefined
        at Object.getPictures (ng-cordova.js:4740)
        at Scope.$scope.getImageSaveContact (controllers.js:41)
        at fn (eval at compile (ionic.bundle.js:27638), :4:248)
        at ionic.bundle.js:65427
        at Scope.$eval (ionic.bundle.js:30395)
        at Scope.$apply (ionic.bundle.js:30495)
        at HTMLButtonElement. (ionic.bundle.js:65426)
        at defaultHandlerWrapper (ionic.bundle.js:16787)
        at HTMLButtonElement.eventHandler (ionic.bundle.js:16775)
        at triggerMouseEvent (ionic.bundle.js:2953)

        Any ideas on solving this?

  3. Thanks for this great tutorial.
    Sir, i would like to use offline storage like PouchDB to store and retrieve images and i have been battling with it for quite some time now.
    And i would be so grateful, if you can put me through with a simple illustration.
    Many thanks.

  4. Hi.. thanks for the tutorial. I am getting error while encoding base64. Don’t make functions within a loop. -> }); line 41 of javascript file .Any solution?

  5. i am getting an error called “Cannot read property ‘getPictures’ of undefined”. please help me! Thanks!

  6. i use it and it works really good, but now when my phone os update to marshmallow, it didnt work, on console log,it says refused, any idea?

  7. Hi… Thanks for the tutorial. Its working for me and I am able to select 10 images using image picker plugin and show those images in my application page. Now how can I fetch all the gallery images at same time without manually selecting the images on a button click? Please help..

  8. I’m getting an error as follows:

    ionic.bundle.js:26794 TypeError: Cannot read property ‘getPictures’ of undefined
    at Object.getPictures (ng-cordova.js:4740)
    at Scope.$scope.getImageSaveContact (controllers.js:41)
    at fn (eval at compile (ionic.bundle.js:27638), :4:248)
    at ionic.bundle.js:65427
    at Scope.$eval (ionic.bundle.js:30395)
    at Scope.$apply (ionic.bundle.js:30495)
    at HTMLButtonElement. (ionic.bundle.js:65426)
    at defaultHandlerWrapper (ionic.bundle.js:16787)
    at HTMLButtonElement.eventHandler (ionic.bundle.js:16775)
    at triggerMouseEvent (ionic.bundle.js:2953)

    Any ideas on solving this?

  9. Hello Gajotres, thanks for the tutorial. But sadly that is not a solution to a problem I am facing right now, I wonder if it happens to you as well. I use cordova-64base-to-gallery plugin, it was working, but now it doesn’t work correctly. It looks like I don’t have permission to access the ios gallery. Then I can’t find any library about ios gallery permission, and I see you don’t any function to ask for permission before accessing the gallery. My question is, do we need explicit permission to access ios gallery?

  10. ERROR: Plugin ‘ImagePicker’ not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.

    I’m getting an error in IOS, but android working fine.
    Any ideas on solving this?

Leave a Reply