Kashaf Shaikh
Kashaf Shaikh

Reputation: 1

How do i load google fonts on the sever side node js

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:

  1. GetGoogleFonts npm package (which was a bad idea, since it was stuck at the installation)
  2. WebFontLoader (Gives "Window is not defined" error)

Steps to Reproduce

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

Answers (2)

Volk
Volk

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

Kaiido
Kaiido

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

Related Questions