【问题标题】:[Node.js, sharp]: Make text take up 100% of SVG width[Node.js, sharp]:使文本占据 SVG 宽度的 100%
【发布时间】:2021-04-28 03:26:10
【问题描述】:

我正在使用sharp image library 向图像添加文本标签。使用 sharp 向图像添加文本的唯一方法是创建一个 svg 并使用复合函数将其应用到源图像上。

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();

但是,我无法让文本正确使用容器中的可用空间。文本应在 svg 中垂直和水平居中。文本应尽可能高,但不会水平溢出容器。

这是我的代码使用不同的 label 值生成的结果:

这是我希望它产生的理想效果:

此外,由于issue in sharp,我不能使用dominant-baseline="middle" 将我的文本垂直居中,而是必须使用dy="0.25em"。我不确定这是否会改变答案,但我认为值得一提。

【问题讨论】:

    标签: node.js svg sharp


    【解决方案1】:

    你可以使用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');
    

    【讨论】:

    • 这似乎不起作用。运行上面将Loooooooooong Text 替换为Loooooooooooooooooooooooong Text 的确切代码仍会导致文本被水平截断(imgur.com/XB9IZ3g)。此外,当将 label 的值更改为 Short 时,文本不会按需要填满可用的垂直空间 (imgur.com/3npyX8a)。也许答案仍然在于viewBox,但有什么方法可以针对不同长度的文本动态调整它?
    【解决方案2】:

    我认为你必须相应地改变高度。

    let width = 100;
    let height = 25;
    let label = "Loooooooooong  Text ";
    let lengthoftext =20;
    

    所以让我们假设这是完美的文本场景。 现在让我们认为文本只有 10 个字符。 所以你保持 width=100 但改变 height = 50;
    依此类推,您的比率 heightnew = (20/lengthoftext) *25。 我认为所有文本的大小都应该相同,您只需确定最大长度是多少,然后将其包装在下一行。

    【讨论】:

    • 我不确定这将如何工作,因为字符串中的每个字符的宽度都不相同。
    猜你喜欢
    • 1970-01-01
    • 2013-06-23
    • 2019-05-17
    • 1970-01-01
    • 2013-07-31
    • 2022-01-25
    • 1970-01-01
    • 2019-03-18
    • 2014-02-03
    相关资源
    最近更新 更多