UNPKG

open-thumbnailer

Version:

An open source thumbnailer framework

187 lines (165 loc) 5.89 kB
var Fs = require('fs'), Gm = require('gm'), Utils = require('./utils'); /** * Represents an individual thumbnail * @param {Number} width The width of the thumbnail in pixels * @param {Number} height The height of the thumbnail in pixels * @param {String} path The path where the thumbnail is located on disk * @param {Number} size The size of the thumbnail in bytes */ function Thumbnail(width, height, path, size) { this._setInfo(width, height, path, size); } /** * Returns an object containing information about the thumbnail. If the * caller has graphicsmagick installed extra information such as the * width and height of the thumbnail will be present */ Thumbnail.prototype.getInfo = function() { return this._info; }; Thumbnail.prototype._setInfo = function(width, height, path, size) { this._info = { width: width, height: height, path: path, size: size }; }; /** * Deletes the thumbnail * @param {Function} callback (error) */ Thumbnail.prototype.destroy = function(callback) { Fs.unlink(this._info.path, function(error) { callback && callback(error); }); }; /** * Creates a copy of the thumbnail */ Thumbnail.prototype.copy = function(outPath, callback) { var readStream = Fs.createReadStream(this._info.path), self = this; readStream.on("error", function(error) { callback(error); }); var writeStream = Fs.createWriteStream(outPath); writeStream.on("error", function(error) { callback(error); }); writeStream.on("close", function() { callback(null, new Thumbnail( self._info.width, self._info.height, outPath, self._info.size )); }); readStream.pipe(writeStream); }; /** * Moves the thumbnail to the targetPath */ Thumbnail.prototype.move = function(targetPath, callback) { var self = this; Fs.rename(this._info.path, targetPath, function(error) { if (error) { callback(error); return; } self._info.path = targetPath; callback(); }); }; /** * Provides the ability to resize and crop the thumbnail * * @param {Object} options * @param {String} [options.targetPath] Optional, if supplied the original * thumbnail will be untouched and a new file will be created. If not specified * then the original thumbnail will be modified * @param {Number} [options.scaleToWidth] * @param {Number} [options.scaleToHeight] */ Thumbnail.prototype.resize = function(options, callback) { var self = this; Utils.gmInstalled(function(error, installed) { if (error) { callback(error); return; } if (!installed) { callback({ unsupported: true, msg: 'graphicsmagick is not installed' }); return; } if (options.targetPath) { self.copy(options.targetPath, function(error, thumbCopy) { if (error) { callback(error); return; } _resize(thumbCopy, false); }); } else { _resize(self, true); } function _resize(thumbnail, overrideThumb) { var targetWidth, targetHeight, cropRegion; if (options.scaleToWidth) { targetWidth = options.scaleToWidth; targetHeight = options.scaleToWidth / thumbnail.getInfo().width * thumbnail.getInfo().height; } else if (options.scaleToHeight) { targetHeight = options.scaleToHeight; targetWidth = options.scaleToHeight / thumbnail.getInfo().height + thumbnail.getInfo().width; } if (options.crop) { cropRegion = options.crop; } else { cropRegion = { top: 0, left: 0, width: targetWidth, height: targetHeight }; } executeGm(targetWidth, targetHeight, cropRegion); function executeGm(targetWidth, targetHeight, crop) { Gm(thumbnail.getInfo().path) .resize(targetWidth, targetHeight) .crop(crop.width, crop.height, crop.left, crop.top) .write(thumbnail.getInfo().path, function(error) { if (error) { callback(error); return; } Fs.lstat(thumbnail.getInfo().path, function(error, stats) { if (error) { callback(error); return; } var finalWidth = Math.min(crop.width, targetWidth), finalHeight = Math.min(crop.height, targetHeight); if (overrideThumb) { thumbnail._setInfo( finalWidth, finalHeight, thumbnail.getInfo().path, stats.size ); callback(); } else { callback(null, new Thumbnail( Math.min(crop.width, targetWidth), Math.min(crop.height, targetHeight), thumbnail.getInfo().path, stats.size )); } }); }); } } }); }; module.exports = Thumbnail;