Composing multiple images generated by Sharp
See original GitHub issueBelow is my code that will generate images of cards. It’s a snippet of a much larger set of code, but only this section is relevant.
It runs up until “Overlaying suit icon…” that’s the last output in the console. After that, “Overlaying card icon…” does not display.
The only way to make it run is to remove .toBuffer from the first promise callback (after Overlaying suit icon).
return sharp(buff).overlayWith(suitIcon, { left: config.get('template.cards.suit-icon.left'), top: config.get('template.cards.suit-icon.top') }).toBuffer();
Becomes
return sharp(buff).overlayWith(suitIcon, { left: config.get('template.cards.suit-icon.left'), top: config.get('template.cards.suit-icon.top') });
And then needless to say the code after that fails to complete. I’ve seen many solutions to overlaying multiple images on top of each other on here, many of them years old and actually I struggle to get any of the examples to work.
With promises / etc I am not expert, so any help is appreciated. Please refrain from tearing my code apart I know it is probably horrible.
var cardImage = sharp(cardPath + 'card-background.svg')
.png()
.toBuffer()
.then(function(buff){
// Red
if( ['heart', 'diamond'].indexOf(cardCombo[card][1]) >= 0 ){
var suitIcon = cardPath + 'icon-'+cardCombo[card][1]+'.svg';
var cardIcon = cardPath + 'icn-'+cardCombo[card][0]+'-red.svg';
}
// Black
else {
var suitIcon = cardPath + 'icon-'+cardCombo[card][1]+'.svg';
var cardIcon = cardPath + 'icn-'+cardCombo[card][0]+'-black.svg';
}
console.log('Overlaying suit icon...');
return sharp(buff).overlayWith(suitIcon, {
left: config.get('template.cards.suit-icon.left'),
top: config.get('template.cards.suit-icon.top')
}).toBuffer();
}).then(function(buffTwo){
console.log('Overlaying card icon...');
console.log(buffTwo.toBuffer());
return sharp(buffTwo, opts).overlayWith(cardIcon, {
left: config.get('template.cards.card-icon.left'),
top: config.get('template.cards.card-icon.top')
}).png().toFile(finalFilePath + '.png');
}).then(function(res){
console.log(res);
}).catch(err => {
console.log(err);
})
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (2 by maintainers)
Top GitHub Comments
Andddd apologies but this seems it was from my lack of Node understanding! Or a quirk in the library, not too sure at this point.
Just in case anyone else gets stuck in a similar headache, if you’re running a large amount of operations in nested promises (.toBuffers()) it seems it wants to finish all of level 1, before it triggers any promises of level 2.
E.g this section of code (green) will finish for all the items in my loop before the second section (red) starts at all, then all items are looped through as intended from what I can tell.
you can do it by await/async like this:
img=await img.overlayWith(uname, { left:320, top:360 }).toBuffer(); img=sharp(img); img = await img.overlayWith(cardid, { left:320, top:405 }).toBuffer(); img=sharp(img);