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]
].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
// 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({
const compositedBuffer = await sharp({
create: {
width: tileSize * 2,
height: tileSize * 2,
channels: 4,
background: { r: 0, g: 0, b: 0, alpha: 0 }
}
}).overlayWith(
topLeft, { gravity: sharp.gravity.northwest }
).png().toBuffer().then((buf) => {
return sharp(buf).overlayWith(
topRight, { gravity: sharp.gravity.northeast }
).png().toBuffer()
}).then((buf) => {
return sharp(buf).overlayWith(
bottomLeft, { gravity: sharp.gravity.southwest }
).png().toBuffer()
}).then((buf) => {
return sharp(buf).overlayWith(
bottomRight, { gravity: sharp.gravity.southeast }
).png().toBuffer()
}).then((buf) => {
return sharp(buf
).resize(tileSize, tileSize, { fit: 'inside' }
).png().toBuffer()
})
}).composite([
{
input: topLeft,
top: 0,
left: 0
},
{
input: topRight,
top: 0,
left: tileSize
},
{
input: bottomLeft,
top: tileSize,
left: 0
},
{
input: bottomRight,
top: tileSize,
left: tileSize
}
]).png().toBuffer();
return sharp(compositedBuffer)
.resize(tileSize, tileSize, {fit: 'inside'})
.png()
.toBuffer();
}
export {