screenshotHandler.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. var debug = require('debug')('ylt:screenshotHandler');
  2. var lwip = require('lwip');
  3. var tmp = require('temporary');
  4. var Q = require('q');
  5. var fs = require('fs');
  6. var path = require('path');
  7. var screenshotHandler = function() {
  8. this.getScreenshotTempFile = function() {
  9. var screenshotTmpFolder = new tmp.Dir();
  10. var tmpFilePath = path.join(screenshotTmpFolder.path, 'screenshot.png');
  11. var that = this;
  12. return {
  13. getTmpFolder: function() {
  14. return screenshotTmpFolder;
  15. },
  16. getTmpFilePath: function() {
  17. return tmpFilePath;
  18. },
  19. toThumbnail: function(width) {
  20. return that.optimize(tmpFilePath, width);
  21. },
  22. deleteTmpFile: function() {
  23. return that.deleteTmpFileAndFolder(tmpFilePath, screenshotTmpFolder);
  24. }
  25. };
  26. };
  27. this.optimize = function(imagePath, width) {
  28. var that = this;
  29. debug('Starting screenshot transformation');
  30. return this.openImage(imagePath)
  31. .then(function(image) {
  32. return that.resizeImage(image, width);
  33. })
  34. .then(this.addWhiteBackground)
  35. .then(this.toBuffer);
  36. };
  37. this.openImage = function(imagePath) {
  38. var deferred = Q.defer();
  39. lwip.open(imagePath, function(err, image){
  40. if (err) {
  41. debug('Could not open imagePath %s', imagePath);
  42. debug(err);
  43. deferred.reject(err);
  44. } else {
  45. debug('Image correctly open');
  46. deferred.resolve(image);
  47. }
  48. });
  49. return deferred.promise;
  50. };
  51. this.resizeImage = function(image, newWidth) {
  52. var deferred = Q.defer();
  53. var currentWidth = image.width();
  54. var ratio = newWidth / currentWidth;
  55. image.scale(ratio, function(err, image){
  56. if (err) {
  57. debug('Could not resize image');
  58. debug(err);
  59. deferred.reject(err);
  60. } else {
  61. debug('Image correctly resized');
  62. deferred.resolve(image);
  63. }
  64. });
  65. return deferred.promise;
  66. };
  67. // If the page doesn't set a bg color, the default PhantomJS one is transparent
  68. // When transforming PNG to JPG, transparent pixels become black.
  69. // This is why we need to add a transparent background.
  70. this.addWhiteBackground = function(image) {
  71. var deferred = Q.defer();
  72. // Create a canvas with the same dimensions as your image:
  73. lwip.create(image.width(), image.height(), 'white', function(err, canvas){
  74. if (err) {
  75. debug('Could not create a white canvas');
  76. debug(err);
  77. deferred.reject(err);
  78. } else {
  79. // Paste original image on top of the canvas
  80. canvas.paste(0, 0, image, function(err, image){
  81. if (err) {
  82. debug('Could not paste image on the white canvas');
  83. debug(err);
  84. deferred.reject(err);
  85. } else {
  86. // Now image has a white background...
  87. debug('White background correctly added');
  88. deferred.resolve(image);
  89. }
  90. });
  91. }
  92. });
  93. return deferred.promise;
  94. };
  95. this.toBuffer = function(image) {
  96. var deferred = Q.defer();
  97. image.toBuffer('jpg', {quality: 90}, function(err, buffer){
  98. if (err) {
  99. debug('Could not save image to buffer');
  100. debug(err);
  101. deferred.reject(err);
  102. } else {
  103. debug('Image correctly transformed to buffer');
  104. deferred.resolve(buffer);
  105. }
  106. });
  107. return deferred.promise;
  108. };
  109. this.deleteTmpFileAndFolder = function(tmpFilePath, screenshotTmpFolder) {
  110. var deferred = Q.defer();
  111. fs.unlink(tmpFilePath, function (err) {
  112. if (err) {
  113. debug('Screenshot file not found, could not be deleted. But it is not a problem.');
  114. } else {
  115. debug('Screenshot file deleted.');
  116. }
  117. screenshotTmpFolder.rmdir();
  118. debug('Screenshot temp folder deleted');
  119. deferred.resolve();
  120. });
  121. return deferred.promise;
  122. };
  123. };
  124. module.exports = new screenshotHandler();