lib/image/index.js
function (dirpath, options, callback) {
        var self = this;

        if (typeof options === 'function') {
            callback = options;
            options = undefined;
        }

        if (!fsys.isDirectorySync(dirpath)) {
            logger.error('not a directory. path:', dirpath);
            callback && callback(new Error('not a directory. path: ' + dirpath));
            return;
        }

        var bucks = new Bucks();
        bucks.empty();

        var tasks = [];
        fsys.walk(dirpath, function filefn(prefix, dir, file, stats) {
            var src = path.join(dir, file);
            tasks.push(function (err, res, next) {
                self.optim(src, options, next);
            });

        });

        var range = options.limit || 10;
        var gtasks = [];

        for(var i = 0; i < Math.ceil(tasks.length / range); i++) {
            var j = i * range;
            var p = tasks.slice(j, j + range);
            gtasks.push(p);
        }

        logger.warn('tasks:', tasks.length); // all task num

        for (var k = 0; k < gtasks.length; k++) {
            bucks.parallel(gtasks[k]);
        }

        bucks.end(function(err, ress) {
            callback && callback(err, ress);
        });


    }
function (dirpath, options, callback) {
        var self = this;

        if (typeof options === 'function') {
            callback = options;
            options = undefined;
        }

        if (!fsys.isDirectorySync(dirpath)) {
            logger.error('not a directory. path:', dirpath);
            callback && callback(new Error('not a directory. path: ' + dirpath));
            return;
        }

        var bucks = new Bucks();
        bucks.empty();

        var tasks = [];
        fsys.walk(dirpath, function filefn(prefix, dir, file, stats) {
            var src = path.join(dir, file);
            tasks.push(function (err, res, next) {
                self.optim(src, options, next);
            });

        });

        var range = options.limit || 10;
        var gtasks = [];

        for(var i = 0; i < Math.ceil(tasks.length / range); i++) {
            var j = i * range;
            var p = tasks.slice(j, j + range);
            gtasks.push(p);
        }

        logger.warn('tasks:', tasks.length); // all task num

        for (var k = 0; k < gtasks.length; k++) {
            bucks.parallel(gtasks[k]);
        }

        bucks.end(function(err, ress) {
            callback && callback(err, ress);
        });


    }
function ( dirpath , options , callback ) { var self = this ; if ( typeof options === 'function' ) { callback = options ; options = undefined ; } if ( ! fsys . isDirectorySync ( dirpath ) ) { logger . error ( 'not a directory. path:' , dirpath ) ; callback && callback ( new Error ( 'not a directory. path: ' + dirpath ) ) ; return ; } var bucks = new Bucks ( ) ; bucks . empty ( ) ; var tasks = [ ] ; fsys . walk ( dirpath , function filefn ( prefix , dir , file , stats ) { var src = path . join ( dir , file ) ; tasks . push ( function ( err , res , next ) { self . optim ( src , options , next ) ; } ) ; } ) ; var range = options . limit || 10 ; var gtasks = [ ] ; for ( var i = 0 ; i < Math . ceil ( tasks . length / range ) ; i ++ ) { var j = i * range ; var p = tasks . slice ( j , j + range ) ; gtasks . push ( p ) ; } logger . warn ( 'tasks:' , tasks . length ) ; // all task num for ( var k = 0 ; k < gtasks . length ; k ++ ) { bucks . parallel ( gtasks [ k ] ) ; } bucks . end ( function ( err , ress ) { callback && callback ( err , ress ) ; } ) ; }
run the recursive directory of  optipng and jpegoptim

@name optimdir
@memberof image
@method
@param {String} dirpath directory root path
@param {String} options options.
@param {function} callback
@example
var filepath = './test/image/logo.jpg';
var options = {
optipng:   { use: true, options: "-o 2"},
jpegoptim: { use: true, options: "--strip-all"}
pngquant: { use: true, options: "--ext .png -f -v"},
limit: 10
}
run the recursive directory of optipng and jpegoptim