Files
YellowLabTools/lib/screenshotHandler.js
T
Paul HooijengaandGaël Métais 3fc0d9418f Use jimp instead of lwip for image processing
Jimp does not install on recent versions of NodeJS because of changes
in the bundled version of zlib. Jimp is a pure JS replacement.
2018-01-16 20:17:34 -06:00

171 lines
4.7 KiB
JavaScript

var debug = require('debug')('ylt:screenshotHandler');
var Jimp = require('jimp');
var tmp = require('temporary');
var Q = require('q');
var fs = require('fs');
var path = require('path');
var screenshotHandler = function() {
this.getScreenshotTempFile = function() {
var screenshotTmpFolder = new tmp.Dir();
var tmpFilePath = path.join(screenshotTmpFolder.path, 'screenshot.png');
var that = this;
return {
getTmpFolder: function() {
return screenshotTmpFolder;
},
getTmpFilePath: function() {
return tmpFilePath;
},
toThumbnail: function(width) {
return that.optimize(tmpFilePath, width);
},
deleteTmpFile: function() {
return that.deleteTmpFileAndFolder(tmpFilePath, screenshotTmpFolder);
}
};
};
this.optimize = function(imagePath, width) {
var that = this;
debug('Starting screenshot transformation');
return this.openImage(imagePath)
.then(function(image) {
return that.resizeImage(image, width);
})
.then(this.addWhiteBackground)
.then(this.toBuffer);
};
this.openImage = function(imagePath) {
var deferred = Q.defer();
Jimp.read(imagePath, function(err, image){
if (err) {
debug('Could not open imagePath %s', imagePath);
debug(err);
deferred.reject(err);
} else {
debug('Image correctly open');
deferred.resolve(image);
}
});
return deferred.promise;
};
this.resizeImage = function(image, newWidth) {
var deferred = Q.defer();
var currentWidth = image.bitmap.width;
var ratio = newWidth / currentWidth;
image.scale(ratio, function(err, image){
if (err) {
debug('Could not resize image');
debug(err);
deferred.reject(err);
} else {
debug('Image correctly resized');
deferred.resolve(image);
}
});
return deferred.promise;
};
// If the page doesn't set a bg color, the default PhantomJS one is transparent
// When transforming PNG to JPG, transparent pixels become black.
// This is why we need to add a transparent background.
this.addWhiteBackground = function(image) {
var deferred = Q.defer();
// Create a canvas with the same dimensions as your image:
new Jimp(image.bitmap.width, image.bitmap.height, 0xFFFFFF, function(err, canvas){
if (err) {
debug('Could not create a white canvas');
debug(err);
deferred.reject(err);
} else {
// Paste original image on top of the canvas
canvas.composite(image, 0, 0, function(err, image){
if (err) {
debug('Could not paste image on the white canvas');
debug(err);
deferred.reject(err);
} else {
// Now image has a white background...
debug('White background correctly added');
deferred.resolve(image);
}
});
}
});
return deferred.promise;
};
this.toBuffer = function(image) {
var deferred = Q.defer();
image.quality(90).getBuffer(Jimp.MIME_JPEG, function(err, buffer){
if (err) {
debug('Could not save image to buffer');
debug(err);
deferred.reject(err);
} else {
debug('Image correctly transformed to buffer');
deferred.resolve(buffer);
}
});
return deferred.promise;
};
this.deleteTmpFileAndFolder = function(tmpFilePath, screenshotTmpFolder) {
var deferred = Q.defer();
fs.unlink(tmpFilePath, function (err) {
if (err) {
debug('Screenshot file not found, could not be deleted. But it is not a problem.');
} else {
debug('Screenshot file deleted.');
}
screenshotTmpFolder.rmdir();
debug('Screenshot temp folder deleted');
deferred.resolve();
});
return deferred.promise;
};
};
module.exports = new screenshotHandler();