Estoy usando la biblioteca de imágenes de Sharp para agregar etiquetas de texto a una imagen. La única forma de agregar texto a una imagen usando sharp es creando un svg y usando la función compuesta para aplicarlo a la imagen de origen.
let width = 100; let height = 25; let label = "Loooooooooong Text"; // "Medium Text" "Short" const label = Buffer.from(` <svg width="${width}" height="${height}"> <rect x="0" y="0" width="100%" height="100%" fill="#fff" /> <text x="50%" y="50%" text-anchor="middle" dy="0.25em" fill="#000">${label}</text> </svg> `); let image = await sharp({ create: { width: width, height: height, channels: 4, background: { r: 255, g: 255, b: 255, alpha: 1 }, } }).composite([{ input: label, top: 0, left: 0, }]).png().toBuffer();Sin embargo, tengo problemas para que el texto utilice correctamente el espacio disponible en el contenedor. El texto debe estar centrado vertical y horizontalmente dentro del svg. El texto debe ser lo más alto posible sin desbordar el contenedor horizontalmente.
Esto es lo que produce mi código con diferentes valores para la label :
Esto es idealmente lo que me gustaría que produjera:
Además, debido a un problema en sharp , no puedo usar dominant-baseline="middle" para centrar mi texto verticalmente y en su lugar debo usar dy="0.25em" . No estoy seguro de si esto cambiaría la respuesta, pero pensé que sería digno de mención incluirlo.
Puedes usar viewBox
const sharp = require('sharp'); const width = 100; const height = 25; const label = "Loooooooooong Text"; // "Medium Text" "Short" const svg = ` <svg width="${width}" height="${height}" viewBox="0 0 ${height} ${height + 2}"> <!--this rect should have rounded corners--> <rect x="0" y="0" width="100%" height="100%" fill="#fff"/> <text x="50%" y="50%" text-anchor="middle" dy="0.25em" fill="#000">${label}</text> </svg> `; const svg_buffer = Buffer.from(svg); const image = sharp({ create: { width: width, height: height, channels: 4, background: { r: 255, g: 255, b: 255, alpha: 1 }, } }) .composite([{ input: svg_buffer, top: 0, left: 0, }]) .png() .toFile('sample.png');Creo que tienes que cambiar la altura en consecuencia.
let width = 100; let height = 25; let label = "Loooooooooong Text "; let lengthoftext =20; Así que supongamos que este es un escenario de texto perfectamente ajustado. Ahora pensemos que el texto tiene solo 10 caracteres. entonces mantienes ancho = 100 pero cambias alto = 50;
y así sucesivamente, toma la relación altura nueva = (20/longitud del texto) * 25. Creo que todo el texto debe tener el mismo tamaño, solo puede asegurarse de cuál es la longitud máxima y luego envolverlo en la siguiente línea.