Build your mobile picture gallery with cordova

Cordova

Ionic

Phonegap

Build your mobile picture gallery with cordova

I thought adding a picture gallery to a cordova app would be a piece of cake when I started a mobile project a few months ago. I was surprised to discover that the large cordova community had never fully developped such a useful plugin!

This article aims to save you a few headaches and help you build a gallery with pictures coming from the picture library on Cordova with the plugin we've forked and enhanced. It also explains how to display those images as squares with the correct orientation and without stretching the pictures, like this:

Finding the right plugin

Every plugin I found digging in the forks of the official plugin was not what I needed.

In order to build a gallery, you are bound to need:

  • to retrieve the pictures from the gallery, ordered by descending date.
  • to limit the number of pictures you receive
  • to have a consistent orientation on every picture whether they are landscape or portrait pictures.
  • thumbnails on Android

So we forked the johnnyoin's plugin to retrieve the pictures from the latest to the n-th, a parameter that you can set.

Example with Android 6 permissions

On Android 6, you will also need to install the permission plugin to ask for the permission to access the gallery. Here is how to use it:

const pictures = [];

const getDevicePictures = (pictureCount) => {
  // CameraRoll is a global object added by the plugin
  CameraRoll.getPhotos((picture) => {
    // picture is an empty object when loading is finished
    if (picture.path) {
      picture.path = picture.path.replace('assets-library://', 'cdvfile://localhost/assets-library/');
      pictures.push(picture);
    }
  }, (err) => {
    console.error('An error occured :(')
  },
  { count: pictureCount });
}

document.addEventListener('deviceready', () => {
  const pictureCount = 7;
  // The following line works only with Ionic, adapt it to your needs
  if (ionic.Platform.isAndroid()) {
    const permissions = cordova.plugins.permissions;
    const readPermission = permissions.READ_EXTERNAL_STORAGE;
    permissions.hasPermission(
      readPermission,
      permissions.requestPermission(readPermission, () => getDevicePictures(pictureCount))
    );
  } else {
    getDevicePictures(pictureCount);
  }
});

Using thumbnails on Android

On iOS, the performance is great on all devices without having to scale down the images.

On Android, displaying multiple high-resolution pictures on a cordova app will make your app painfully slow. To fix that, the only solution we found was to retrieve thumbnails instead of the full images.

CameraRoll.getPhotos((picture) => {
  // `picture` is an object with a `path`, a `date`
  // on android there is a`thumbnailPath` that you can use to display a thumbnail.
  console.log(picture);
}

Displaying not stretched images with the correct orientation

When you have retrieved the pictures, the challenge is to display them as square, without stretching them and keeping the good image orientation.

This orientation issue is fixed by using an html img element, but it prevents you from using the css property background-size: cover which usually fix stretching issues.

Hopefully there is an awesome css property that will do the trick, object-fit.

Here is an example in AngularJs:

<div
  class="thumbnail"
  ng-repeat="picture in pictures"
>
  <img
    class="image"
    ng-src=""
  />
</div>

with the following css:

.thumbnail {
  width: 33vw;
  height: 33vw;
}

.image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

You can easily get a gallery which looks like this:

image1.jpg

 

Fixing orientation issues on Android

Your camera roll should now be functional, but the Android thumbnails are likely to appear rotated.

To fix this, the plugin also returns the orientation of the picture on android. It can be use with a transform: rotatelike this in AngularJs:

div
<div
  class="thumbnail"
  ng-repeat="picture in pictures"
>
  <img
    class="image"
    ng-style="{'transform': 'rotate(' + (picture.orientation || 0) + 'deg)'}"
    ng-src=""
  />
</div>

Now you should have a fully functional and good looking picture gallery!

Contributing to cordova-camera-roll

Pull requests are welcome!

Camera roll on React-native

If you are more a react-native person, at BAM we made a plugin too a few months ago, but now the CameraRoll API of React Native has a full support out-of-the-box of iOS and Android. Yay!