How to create a screenshot of your app in Cordova

How to create a screenshot of your app in Cordova

Although to require the creation of a screenshot in your app is not so usual, it may be useful to create detailed error reports (made by the user or even automatically). In this article, you'll learn how to create a screenshot in you cordova application easily.

Requirements

In order to create screenshots in your app, we are going to depend on the cordova-screenshot plugin. The Screenshot plugin allows your application to take screenshots of the current screen and save them into the phone easily.

To install this plugin in your project, execute the following command in the command prompt:

cordova plugin add https://github.com/gitawego/cordova-screenshot.git

The Screenshot plugin allows your application to take screenshots of the current screen and save them into the phone. The plugin will create a property named screenshot in the navigator object of the browser and will expose 2 methods (save and URI).

Implementation

What makes this plugin different to others, is that it checks whether your cordova project (in Android) uses wheter the XWalkWebViewEngine or the android web view and according to that will create the screenshot respectively. In iOS it will create a bitmap context of the size of your screen and will create an image with UIGraphicsBeginImageContextWithOptions and UIGraphicsGetImageFromCurrentImageContext, finally will convert the image to JPEG (in iOS only JPEG is supported) and then save it (or return the base64 uri).

Create and save screenshot

The plugin either in iOS and Android, will need to create a file (image) in the device storage (/sdcard/Pictures for android). However, you can't set the location of the screenshot., the path where the generated screenshot is located will be returned in the response callback (if you need to set the location of the screenshot, you can retrieve the image in Base64 format and then save it, for more information read the next section Get screenshot in Base64 format).

The screenshot.save method expects up to 4 arguments (3 optional):

  • callback: a callback that follows the node async code style. The callback receives 2 parameters, the error[1] and the response[2, an object with the filePath property]. 
  • format: a string (png or jpg) that specifies the desired format of the image.
  • quality: an integer from 0 to 100 that specifies the quality of the image if available.
  • filename: you can change the filename of the image if you want, otherwise a random name will be generated (screenshot_XXXXXXXXXX.jpg).

To create your first screenshot, you can use:

navigator.screenshot.save(function(error,response){
    if(error){
        console.error(error);
        return;
    }
    
    // Something like: /storage/emulated/0/Pictures/screenshot_1477924039236.jpg
    console.log(response.filePath);
});

Besides, if you want to change the quality and the output filename, then you can use:

navigator.screenshot.save(function(error,response){
    if(error){
        console.error(error);
        return;
    }

    // Something like: /storage/emulated/0/Pictures/myScreenShot.jpg
    console.log(response.filePath);
},'jpg',50,'myScreenShot');

Get screenshot in Base64 format

You can take a screenshot and get it as Data URI using the screenshot.URI method. This method expects 2 parameters (1 optional):

  • callback: a callback that follows the node async code style. The callback receives 2 parameters, the error[1] and the response[2, an object with the URI property]. 
  • quality: an integer from 0 to 100 that specifies the quality of the image if available.

screenshot.URI creates a temporal image in the device storage and then returns the Data URI. This method comes in handy if you need to handle images with ajax calls and you can use it like:

navigator.screenshot.URI(function(error,response){
    if(error){
        console.error(error);
        return;
    }

    // Something like: data:image/jpeg;base64,/9j/4AAQSkZJ
    console.log(response.URI);
}, 50);

The only limitation of this plugin is to customize the output path of the file, however you can create a workaround by saving the Base64 string as an image in the device using the cordova-file-plugin as specified in this article. Using the method described in the article, you can save the Data URI as a file in the device with the destination that you want:

/** Process the type1 base64 string **/
var myBaseString = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkYAAA.....";

// Split the base64 string in data and contentType
var block = myBaseString.split(";");
// Get the content type
var dataType = block[0].split(":")[1];// In this case "image/png"
// get the real base64 content of the file
var realData = block[1].split(",")[1];// In this case "iVBORw0KGg...."

// The path where the file will be created
var folderpath = "file:///storage/emulated/0/";
// The name of your file, note that you need to know if is .png,.jpeg etc
var filename = "myimage.png";

savebase64AsImageFile(folderpath,filename,realData,dataType);

Angular service

You can add the following service in your project in case that you're using Angular (ionic):

.service('$cordovaScreenshot', ['$q', function ($q){
    return {
        capture: function (filename, extension, quality){
            extension = extension || 'jpg';
            quality = quality || '100';

            var defer = $q.defer();

            navigator.screenshot.save(function (error, res){
                if (error) {
                    console.error(error);
                    defer.reject(error);
                } else {
                    console.log('screenshot saved in: ', res.filePath);
                    defer.resolve(res.filePath);
                }
            }, extension, quality, filename);

            return defer.promise;
        }
    };
}])

Known issues

In some android platforms, mainly in projects that use crosswalk you'll receive a black image as result of the screenshot. To prevent this behaviour, you can add the following parameter in your config.xml file:

<preference name="CrosswalkAnimatable" value="true" />

You can read more about the bug here, however this issue seems to be solved since Crosswalk 14.

Have fun !

Become a more social person