Simplify tile stitching with sharp

The new method uses the composite() method of sharp
to reduce the number of times a PNG buffer is created.
The number could be further reduced from two to one,
if the issue #1908 from lovell/sharp is resolved so that
composite and resize can be chained without an
intermediate call to .png().toBuffer()
This commit is contained in:
Maciej Ziarkowski 2019-10-07 16:21:36 +01:00
parent 5417b5c8b6
commit 14b79ce891

View File

@ -18,35 +18,40 @@ async function stitchTile({ tileset, z, x, y, scale }: TileParams, dataParams: a
[nextXY.maxX, nextXY.maxY] [nextXY.maxX, nextXY.maxY]
].map(([x, y]) => renderTile({ tileset, z: nextZ, x, y, scale }, dataParams))); ].map(([x, y]) => renderTile({ tileset, z: nextZ, x, y, scale }, dataParams)));
// not possible to chain overlays in a single pipeline, but there may still be a better const compositedBuffer = await sharp({
// way to create image buffer here (four tiles resize to one at the next zoom level)
// instead of repeatedly creating `sharp` objects, to png, to buffer...
return sharp({
create: { create: {
width: tileSize * 2, width: tileSize * 2,
height: tileSize * 2, height: tileSize * 2,
channels: 4, channels: 4,
background: { r: 0, g: 0, b: 0, alpha: 0 } background: { r: 0, g: 0, b: 0, alpha: 0 }
} }
}).overlayWith( }).composite([
topLeft, { gravity: sharp.gravity.northwest } {
).png().toBuffer().then((buf) => { input: topLeft,
return sharp(buf).overlayWith( top: 0,
topRight, { gravity: sharp.gravity.northeast } left: 0
).png().toBuffer() },
}).then((buf) => { {
return sharp(buf).overlayWith( input: topRight,
bottomLeft, { gravity: sharp.gravity.southwest } top: 0,
).png().toBuffer() left: tileSize
}).then((buf) => { },
return sharp(buf).overlayWith( {
bottomRight, { gravity: sharp.gravity.southeast } input: bottomLeft,
).png().toBuffer() top: tileSize,
}).then((buf) => { left: 0
return sharp(buf },
).resize(tileSize, tileSize, { fit: 'inside' } {
).png().toBuffer() input: bottomRight,
}) top: tileSize,
left: tileSize
}
]).png().toBuffer();
return sharp(compositedBuffer)
.resize(tileSize, tileSize, {fit: 'inside'})
.png()
.toBuffer();
} }
export { export {