Reputation: 1
I am using node js and canvas to create an API that writes text on a certain image. I successfully created a route such as -> /:sometext/:fontsize/:color/:position-x/:position-y and sends a static image with the text of the given font-size, color, and position on the canvas.
What I am unable to achieve is that I want to send the font family in the route and have that rendered on the screen. Plus, isn't there any other way that I can load at least google fonts without having to download the .ttf file.
What I have tried:
Currently, I am using a ttf file to load the font
router.get('/thumbnail/:name/:fontsize/:color/:posx/:posy', function (req, res, next) {
let name = req.params.name;
let fontsize = req.params.fontsize
let positionx = req.params.posx
let positiony = req.params.posy
let color = req.params.color
let myimage = 'static/image1.jpg'
const canvas = createCanvas(2000, 1000)
const ctx = canvas.getContext('2d')
var str = "hi "+name
registerFont('AvenirNext.ttf', { family: 'Avenir Next' })
loadImage(myimage).then((image) => {
ctx.drawImage(image, 0 , 0, 2000, 1000);
ctx.font = fontsize + "px Avenir Next"
ctx.fillStyle = color
ctx.fillText(str, positionx, positiony);
const out = fs.createWriteStream(__dirname + '/test.jpeg')
const stream = canvas.createJPEGStream()
stream.pipe(res)
out.on('finish', () => console.log('The JPEG file was created.'))
})
});
Upvotes: 0
Views: 5167
Reputation: 31
If you don't want to host the ttf files on your own server you could try to use the Google Font Github repo.
// missing imports
const http = require('http');
const fs = require('fs');
const fontFamily = req.params.fontfamily; // example: ArchivoNarrow
// download font from github
const file = fs.createWriteStream(fontFamily + '.ttf');
const request = http.get('https://github.com/google/fonts/blob/master/ofl/' + fontFamily.toLowerCase() + '/' + fontFamily + '-Regular.ttf?raw=true', function(response) {
response.pipe(file);
});
registerFont(fontFamily + '.ttf', { family: fontFamily });
// delete font after the image is created
try {
fs.unlinkSync(fontFamily + '.ttf');
} catch(err) {
console.error(err);
}
Font I used for this example: ArchivoNarrow
Upvotes: 1
Reputation: 136766
From the docs for registerFont
To use a font file that is not installed as a system font, use registerFont() to register the font with Canvas. This must be done before the Canvas is created.
emphasis not mine
You are calling it after you created your canvas.
// first register the font
registerFont('AvenirNext.ttf', { family: 'Avenir Next' });
// then create the canvas
const canvas = createCanvas(2000, 1000);
const ctx = canvas.getContext('2d');
var str = "hi " + name;
But note that this will try to load a font that would be available on your server. If you want to make it target a font on ://fonts.googleapis.com server, you'd need to pass the full URI to the font file (not for the .css).
Also, you should wrap your family name inside quotes ("
) since it contains a space:
ctx.font = fontsize + 'px "Avenir Next"';
Upvotes: 0