How to Overlay Text on an Image using JavaScript with Sharp Package
This is a short and sweet article about overlaying text on an image using NodeJS and Sharp library. Recently, I used the Jimp package for some image processing tasks but I had to switch from Jimp to Sharp JS library because of some reasons.
Why Choose Sharp over Jimp for Image Processing in NodeJS?
I was using the Jimp JS library to do some image processing tasks. In the dev environment, it worked well (because I didn't check about the memory usage and the speed) and Jimp has all the fancy features I needed. Overlaying text on an image is a very easy task by using the Jimp package. But I switched from Jimp to Sharp for image processing because Jimp is too slow and it takes more than 1Gb memory to process a 1Mb image :p
Some guys have actually opened a few issues in the Jimp repository but I couldn't find a working solution for this inefficient memory usage. You can refer to the following links if you would like to check those GitHub issues.
I went for the Sharp library after going through many articles that give an analytical comparison between image processing packages in NodeJS. The Sharp package is the best when it comes to time and memory efficiency. You can refer to the following articles to go through those comparisons.
The most challenging task after switching to the Sharp package was overlaying text with a background over an image. But I found out how to do that easily after an hour of web browsing. So... let's go for some coding ;)
How to Overlay a Text with a Background over an Image Using Sharp Package
There's no built-in method in the Sharp package to overlay text over an image. However, it has an inbuilt method to overlay an image over another image. The trick is to create an SVG image with a text and a background for that text. Then you can overlay that SVG image over another image. This method is even more customizable than the inbuilt text overlay function in the Jimp library. You can create and customize that SVG as you wish. Check the following code for a sample.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const sharp = require("sharp"); | |
// The first parameter can be an imageUrl or an image buffer | |
async function overlayText(imageUrl, textToOverlay) { | |
// Create the SVG image with textToOverlay | |
const textedSvg = ` | |
<svg> | |
<rect x="0" y="0" width="200" height="50" /> | |
<text x="10" y="10" font-size="32" fill="#fff">${textToOverlay}</text> | |
</svg> | |
`; | |
const textedSVGBuffer = new Buffer.from(textedSvg); | |
// Overlay the textedSVG in the top left corner of the image (x=0 and y=0) | |
const textOverlayedImage = await sharp(mainImageBuffer) | |
.composite([ | |
{ | |
input: textedSVGBuffer, | |
top: 0, | |
left: 0, | |
} | |
]) | |
.jpeg({quality: 100}) | |
.toBuffer(); | |
// Returns the buffer of the image that coposited the text with a background | |
return textOverlayedImage; | |
} |
The above JavaScript function receives the base image URL (you can pass the image buffer also) and the text to be composited on the image. Then it creates the SVG including a black background with white text.
- The black background (rectangle) is created by the code: <rect x="0" y="0" width="200" height="50" />
- The text is marked up with a 10px gap to the top and left by using the code: <text x="10" y="10" font-size="32" fill="#fff">${textToOverlay}</text>
Then we composite that SVG buffer on the base image by using the Sharp library and convert it to a JPEG image buffer. That's it. Will write a full tutorial about using the Sharp image processing JS library later. Until then, byeee.
0 Comments
Post a Comment