在amazon lambda node.js中将一个大图像分割成一个平铺
我的问题需要一个适当的解决方案。所以我希望你们能帮助我。 这是我的问题。我正在使用node.js graphicmagic处理lambda aws。 在我的aws S3文件夹中,我有一个16000x8000 jpg图像。 当我从s3下载图像时,可以调整大小并裁剪为512x512大小的瓷砖。 但当我通过toBuffer命令将所有生成的tile保存回S3时,会导致错误:流产生空缓冲区 这是我写的代码在amazon lambda node.js中将一个大图像分割成一个平铺,node.js,amazon-s3,lambda,aws-lambda,graphicsmagick,Node.js,Amazon S3,Lambda,Aws Lambda,Graphicsmagick,我的问题需要一个适当的解决方案。所以我希望你们能帮助我。 这是我的问题。我正在使用node.js graphicmagic处理lambda aws。 在我的aws S3文件夹中,我有一个16000x8000 jpg图像。 当我从s3下载图像时,可以调整大小并裁剪为512x512大小的瓷砖。 但当我通过toBuffer命令将所有生成的tile保存回S3时,会导致错误:流产生空缓冲区 这是我写的代码 var clone = require('clone'); var fs = require('fs
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
}
});
});
};
var clone=require('clone');
var fs=需要('fs');
var os=要求(“os”);
var async=require(“异步”);
var gm=require(“gm”).subClass({imageMagick:true});
//要求(“gm-buffer”);
var AWS=要求(“AWS sdk”);
var s3=新的AWS.s3();
exports.handler=函数(事件、上下文){
var bucketPath=event.bucketPath;
var baseDestinationPath=event.baseDestinationPath;//lambda/
//var bufferedImagePath=event.bufferedImagePath;//lambda/JFEmYgjxt4sG-equirectangle_16384.jpg
var bufferedImagePath=event.bufferedImagePathSmall;//lambda/
var最佳分辨率水平=4;
var-minIndex=2;
var分辨率=[416832166433286656];
var tileSize=512;
变量_level2={
索引:2,
宽度:1664,
身高:832,
destinationPath:baseDestinationPath+“级别-”+2
};
变量_级别3={
索引:3,
宽度:3328,
身高:1664,
destinationPath:baseDestinationPath+“级别-”+3
};
变量_级别4={
索引:4,
宽度:6656,
身高:3328,
destinationPath:baseDestinationPath+“级别-”+4
};
var _SizeArray=[];
s3.getObject({
桶:bucketPath,
键:BuffereImage路径
},函数(错误,数据){
if(err){context.fail(err);}
gm(数据。主体)。尺寸(功能(错误,尺寸){
if(err){context.fail(err);}
var full_width=size.width;
var full_height=size.height;
if(全宽<分辨率[2])
{
失败(“{”errorMessage:“小图像”,“errorType:“小”,“成功代码”:0}”);
}
其他的
{
for(var index=4;index>=0;index--)//获取最佳分辨率级别
{
if(全宽>=分辨率[索引])
{
最佳分辨率水平=指数;
打破
}
}//结束最佳分辨率级别
for(var index=2;index=4)//原始图像分辨率(创建最大分辨率图像)
{
层宽度=分辨率[索引];
层高度=分辨率[索引]/2;
}
其他的
{
层宽度=全宽度;
层高度=全层高度;
}
}
其他的
{
层宽度=分辨率[索引];
层高度=分辨率[索引]/2;
}//结束检查最大分辨率
开关(索引){
案例2:{
_level2.width=层宽度;
_level2.height=层高度;
_尺寸排列推送(2级);
打破
}
案例3:{
_level3.width=层宽度;
_level3.height=层高度;
_大小排列。推送(_级别3);
打破
}
案例4:{
_level4.width=层宽度;
_level4.height=层高度;
_尺寸排列推送(4级);
打破
}
}
}//已创建最终结果大小
//问题代码在这里
forEachOf(_size数组,函数(值,键,回调){
异步瀑布([
功能下载(下一步){
s3.getObject({
桶:bucketPath,
键:BuffereImage路径
},下一页);
},
函数转换(数据,下一步){
var gm_object=gm(data.Body).setFormat('JPEG');
下一步(null,gm_对象);
},
函数大小调整器(对象,下一个){
变量宽度=_sizesArray[key]。宽度;
变量高度=_sizesArray[键]。高度;
var gm_object=object.resize(宽度、高度);
下一步(null,gm_对象);
},
函数croper(对象,下一个){
var响应=null;
变量x=0,y=0;
变量宽度=_sizesArray[key]。宽度;
变量高度=_sizesArray[键]。高度;
钙质(x,y);
函数钙质(x,y){
如果(y<(高度/瓷砖尺寸)){
钙质(x,y);
}
否则{
//收成
下一个(空);
}
}
函数calcCropX(x,y){