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 !