tilestrata-gm插件和 tilestrata-sharp 功能上类似,背后使用的依赖graphicsmagickgm库来做图像处理,所以具体能够实现的哪些功可以去 gm 的文档中查询。

demo 项目可以参考tilestrata-sample-code

安装

由于插件依赖于graphicsmagick,需要根据安装指南在各个平台下进行安装,MacOS 可以直接用 brew 安装

$ brew install graphicsmagick
# 再安装插件
$ npm install tilestrata-gm --save

使用

const tilestrata = require('tilestrata')
const mapnik = require('tilestrata-mapnik')
const gm = require('tilestrata-gm')
const server = tilestrata()

server
.layer('world_merc_gm')
.route('tile.png')
.use(
// 定义数据源
mapnik({
pathname: 'style/world.xml'
})
)
.use(
gm(function(image) {
return image
.blur(7, 3) // 模糊处理
.rotate('green', 45) // 旋转,配色
})
)

// 可以同时能处理的任务的个数
gm.setMaxConcurrency(2)

// 启动服务
server.listen(9527)

效果

demo 项目可以参考tilestrata-sample-code

下图是原始的瓦片样式:

使用 gm 插件进行了模糊处理,旋转了 45°,背景填充为绿色后的结果:

代码浅析

插件的整体逻辑和 tilestrata-sharp 基本一致,在toBuffer阶段有所不同,gm 选择了在async.queue队列中逐步转化成 buffer 再返回给 tiletrata,这也是为什么会有setMaxConcurrency这个方法的原因。

// 代码有所精简
// toBuffer队列
var gmQueue = async.queue(function(image, callback) {
image.toBuffer(function(err, buffer) {
callback(err, buffer);
});
}, concurrency);

transform: function(server, req, buffer, headers, callback) {
var image;

try {
// 创建gm对象
image = gm(buffer);
// 执行回调函数里面的处理规则
fn(image);
}
catch (err) { return callback(err); }

// 放入async.queue中,逐步执行
gmQueue.push(image, function(err, buffer) {
if (err) return callback(err);
if (image._outputFormat) {
headers['Content-Type'] = 'image/' + image._outputFormat;
}
callback(null, buffer, headers);
});
}