javascript 使用fontsize计算文本长度(NPM -PDF 2 JSON库)

mcdcgff0  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(127)

我正在使用pdf2json library解析一个pdf。
它在json中返回解析后的数据,我附加了一些示例数据。
需要注意的主要变量有

高度-pdf的高度,以PAGE_UNITS为单位
宽度-pdf的宽度,以PAGE_UNITS为单位
sw-(字体的空间宽度)在README.mdpd 2 json库的www.example.com中定义
索引1处的TS-以pt为单位的字体大小
w-我的困惑发生在哪里。W应该代表文本行的宽度。然而,我的文本行的宽度比页面的宽度大,这没有任何意义。

我需要得到文本的长度。我试着做(文本中的字符数 * sw)/pagewwidth来得到行相对于pdf的比率。Tp测试然后我在前端使用这个比率在特定行上绘制相同pdf的图像。
但这条线的长度似乎不对,通常都太短了。
如果有人能帮忙,我将不胜感激。我一直在通过pd 2 json的问题,寻找类似的东西,但没有答案,库似乎没有得到很好的支持。

"Pages": [
  {
    "Height": 49.5,
    "HLines": [],
    "VLines": [],
    "Fills": [
      {
        "x": 0,
        "y": 0,
        "w": 0,
        "h": 0,
        "clr": 1
      },
      {
        "x": 9.001,
        "y": 19.271,
        "w": 5.372,
        "h": 0.038,
        "clr": 35
      }
    ],
    "Texts": [
      {
        "x": 4.252,
        "y": 45.981,
        "w": 96.648,
        "sw": 0.32553125,
        "clr": 0,
        "A": "left",
        "R": [
          {
            "T": "Hello%20World%20",
            "S": -1,
            "TS": [
              0,
              15,
              0,
              0
            ]
          }
        ]
      },
 "Width": 38.25
...
5vf7fwbs

5vf7fwbs1#

我来得有点晚了,也是为了解决同样的问题,我相信w属性是文本边框的宽度,而不是文本长度,正如您已经注意到的那样。
除非字体是等宽的,否则我不认为我们可以使用字符数来精确地获得文本宽度。
由于HTML5Canvas元素内置了measureText,我决定使用节点canvas尝试下面的代码

import { createCanvas } from 'canvas';
...
const canvas = createCanvas(900, 200); //for text length calcs
const ctx = canvas.getContext('2d');//for text length calcs
const pdfUnitToPx = 22.2281951; //magic scale factor from https://github.com/modesty/pdf2json/issues/123
...
/**
 * getTextWidth
 * calculate text width using canvas
 * @param {pdf2jsonParsedItem} item 
 * @param {CanvasRenderingContext2D} ctx 
 * @returns 
 */
 const getTextWidth = (item,ctx)=>{ 
    //loop through the R elements
    return item.R.reduce((acc,cur)=>{
        //decode the text
        const text = decodeURIComponent(cur.T);
        
        //parse the TS components from pdf2json documentation
        const [fontFaceID,fontSize,fontBold,fontItalic] = cur.TS;
        
        //determine the font face from PDFParser.fontFaceDict which I call pdf2jsonFontFaceDict here
        const fontFace = fontFaceID in pdf2jsonFontFaceDict ? pdf2jsonFontFaceDict[fontFaceID] : 'Arial';
        
        //construct the font style for the canvas
        ctx.font = `${fontBold ? 'bold':''} ${fontItalic ? 'italic':''} ${fontSize}px ${fontFace}`.trim(); //TODO
        
        //use canvas to determine the pixels and convert to pdf units, appending to the accumulator
        acc+= ctx.measureText(text).width / pdfUnitToPx; 
        return acc;
    },0);
}

这还没有通过单元测试,所以我不能保证它的准确性。但是到目前为止,它能很好地满足我的需求。而且开销也没有我想象的那么大。
希望这能帮助到其他人。

相关问题