将一个大图像切成亚马逊lambda node.js

时间:2017-01-30 08:34:00

标签: node.js amazon-s3 lambda aws-lambda graphicsmagick

我需要一个适合我问题的解决方案。所以我希望你们可以帮助我。 这是我的问题。我正在使用node.js graphicmagic工作lambda aws。 在我的aws S3文件夹中,我有一个16000x8000 jpg图像。 当我从s3下载图像是好的,然后调整大小并裁剪为512x512大小的瓷砖是好的。 但是当我通过toBuffer命令将所有生成的tile保存回S3时,它会导致Error:Stream产生空缓冲区。

这是我写的代码。

var clone = require('clone');
var fs = require('fs');
var os = require('os');
var async = require("async");

var gm = require("gm").subClass({imageMagick: true});
//         require('gm-buffer');

var AWS = require("aws-sdk");
var s3 = new AWS.S3();

exports.handler = function(event, context) {

    var bucketPath = event.bucketPath;
    var baseDestinationPath =  event.baseDestinationPath; // lambda/
    // var bufferedImagePath = event.bufferedImagePath; // lambda/JFEmYgjxt4sG-equirectangular_16384.jpg
    var bufferedImagePath = event.bufferedImagePathSmall; // lambda/

    var bestResolutionLevel = 4;
    var minIndex = 2;
    var resolutions =[416, 832, 1664, 3328, 6656];
    var tileSize = 512;
    var _level2 = {
        index: 2,
        width: 1664,
        height: 832,
        destinationPath: baseDestinationPath +"level-" + 2
    };
    var _level3 = {
        index: 3,
        width: 3328,
        height: 1664,
        destinationPath: baseDestinationPath + "level-" + 3
    };
    var _level4 = {
        index: 4,
        width: 6656,
        height: 3328,
        destinationPath: baseDestinationPath + "level-" + 4
    };
    var _sizesArray = [];

    s3.getObject({
        Bucket: bucketPath,
        Key: bufferedImagePath
    }, function(err, data) {

        if (err) { context.fail(err); }

        gm(data.Body).size(function(err, size) {

            if (err) { context.fail(err); } 

            var full_width = size.width;
            var full_height = size.height;

            if( full_width < resolutions[2])
            {
                context.fail('{"errorMessage": "Small Image", "errorType": "small", "successCode": 0}');
            }
            else
            {
                for(var index = 4; index >= 0; index--)  // get best resolution levels
                {
                    if(full_width >= resolutions[index]) 
                    {
                        bestResolutionLevel = index;
                        break;
                    }
                } // end best resolution levels

                for(var index = 2; index <= bestResolutionLevel; index++ )
                {
                    var layer_width = 0, layer_height = 0;

                    if( index == bestResolutionLevel ) // check this is max resolution
                    {
                        if( bestResolutionLevel >= 4 ) // orignal image resolution (create max resolution image)
                        {
                            layer_width = resolutions[index];
                            layer_height = resolutions[index] / 2;
                        }
                        else
                        {
                            layer_width = full_width;
                            layer_height = full_height;
                        }
                    }
                    else
                    {   
                        layer_width = resolutions[index];
                        layer_height = resolutions[index] / 2;
                    } // end check max resolution

                    switch(index) {
                        case 2: {

                            _level2.width = layer_width;
                            _level2.height = layer_height;
                            _sizesArray.push(_level2);
                            break;
                        }
                        case 3: {

                            _level3.width = layer_width;
                            _level3.height = layer_height;
                            _sizesArray.push(_level3);
                            break;
                        }
                        case 4: {

                            _level4.width = layer_width;
                            _level4.height = layer_height;
                            _sizesArray.push(_level4);
                            break;                            
                        }
                    }   
                } // End resulation sizes created

                // Problem code is here
                async.forEachOf(_sizesArray, function(value, key, callback) {
                    async.waterfall([

                        function download(next) {

                            s3.getObject({
                                Bucket: bucketPath,
                                Key: bufferedImagePath
                            }, next); 
                        },
                        function convert(data, next) {

                            var gm_object = gm(data.Body).setFormat('JPEG');

                            next(null, gm_object);
                        },
                        function resizer(object, next) {

                            var width = _sizesArray[key].width;
                            var height = _sizesArray[key].height;
                            var gm_object = object.resize(width, height);

                            next(null, gm_object);
                        },
                        function croper(object, next) {

                            var response = null;
                            var x = 0, y = 0;
                            var width = _sizesArray[key].width;
                            var height = _sizesArray[key].height;

                            calcCropY(x, y);
                            function calcCropY(x, y) {

                                if( y < (height/tileSize) ) {

                                    calcCropX(x, y);
                                }
                                else {

                                    // END CROP
                                    next(null);
                                }
                            }

                            function calcCropX(x, y) {

                                if( x < (width/tileSize) ) {

                                    // do something
                                    var position_x = x * tileSize;
                                    var position_y = y * tileSize;
                                    var clonedObject = clone(object);
                                    var gm_object = clonedObject.crop(tileSize, tileSize, position_x, position_y);

                                    // This code is big problem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                                    gm_object.toBuffer(function(err, buffer) {

                                        if (err) { next(err); } 
                                        else {

                                            s3.putObject({
                                                Bucket: bucketPath,
                                                Key: _sizesArray[key].destinationPath + "/X" + x + "Y" + y + ".jpg",
                                                Body: buffer,
                                                ContentType: 'JPG'
                                            }, function(err) {

                                                x ++;
                                                calcCropY(x, y);
                                            });
                                        }
                                    });
                                }
                                else {
                                    x = 0;
                                    y ++;
                                    calcCropY(x, y);
                                }
                            }
                        }
                    ], function(err, result) {

                        if (err) { console.error(err); }
                        callback();
                    });
                }, function(err) {

                    if (err) 
                    { 
                        console.error(err);
                        context.fail(err);
                    }
                    else
                    {
                        console.log("Successfully done!");
                        context.done();
                    }
                }); // End image processing 
            }
        });
    });
};

任何帮助都会很感激。

0 个答案:

没有答案