从PDF创建图像(PNG或JPEG)以及图像中文本的HTML图像映射?

从PDF创建图像(PNG或JPEG)以及图像中文本的HTML图像映射?,html,pdf,imagemap,Html,Pdf,Imagemap,我正在记录我维护的系统。此文档包含我在TeX/TikZ中创建的一个图表,该图表将呈现为PDF文件。然后我将PDF文件转换为图像文件(通过imagemagick转换为PNG),并将其包含在HTML文档中。效果很好 现在,我想为该图像创建一个,这样我就可以添加超链接/鼠标盖/等等。这是一个我希望根据系统中的更改定期更新的图像,所以如果可能的话,我想自动化这个过程 当PDF文件渲染为PNG时,是否有方法使用软件库或工具自动创建PDF文件中各种文本内容的图像映射? 以下是我创建的一个示例: 在本例中,

我正在记录我维护的系统。此文档包含我在TeX/TikZ中创建的一个图表,该图表将呈现为PDF文件。然后我将PDF文件转换为图像文件(通过imagemagick转换为PNG),并将其包含在HTML文档中。效果很好

现在,我想为该图像创建一个,这样我就可以添加超链接/鼠标盖/等等。这是一个我希望根据系统中的更改定期更新的图像,所以如果可能的话,我想自动化这个过程

当PDF文件渲染为PNG时,是否有方法使用软件库或工具自动创建PDF文件中各种文本内容的图像映射?

以下是我创建的一个示例:

在本例中,我希望通过在PDF中定位各种文本字符串的边界框,将其转换为超链接:

  • 控制器
  • 执行器
  • 传感器
  • A
  • B
  • C
  • D
  • u
  • y
  • F(s)
  • G(s)
  • H(s)
(它们都是PDF文件中的文本内容;我可以在Acrobat Reader中选择其中任何一个的文本,然后复制并粘贴到我的文本编辑器中。)


有办法做到这一点吗?

嗯。我找到了ApachePDFBox库,其中包含一个名为的示例,它可以打印信息,但我不确定如何解释它,每个glyph只有一个位置

> java -jar print_text_locations.jar blockdiagram_example.pdf
String[37.864998,13.939003 fs=4.9813 xscale=4.9813 height=2.49065 space=2.4906502 width=5.1197815]+
String[59.185997,13.662003 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=6.6450577]A
String[130.229,13.662003 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=6.64505]B
String[198.783,13.498001 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=7.192993]C
String[86.827,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=9.699257]H
String[97.449005,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[102.00201,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.5137405]s
String[107.51601,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536])
String[156.35,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=9.234192]G
String[165.58301,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[170.136,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.513733]s
String[175.65,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536])
String[12.797,29.332 fs=9.9626 xscale=9.9626 height=4.9813 space=4.9813004 width=5.7035875]u
String[38.711,27.432999 fs=4.9813 xscale=4.9813 height=3.4022279 space=2.4906502 width=5.39624]?
String[214.641,29.332 fs=9.9626 xscale=9.9626 height=4.9813 space=4.9813004 width=4.884659]y
String[85.109,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]c
String[88.5959,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[92.473335,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]n
String[96.35077,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387131]t
String[98.28948,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
String[100.611755,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[104.48919,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.5481873]l
String[106.03738,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.5481873]l
String[107.58556,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]e
String[111.463,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
String[155.67801,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]a
String[159.55544,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4868927]c
String[163.04233,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387207]t
String[164.98105,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]u
String[168.85847,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]a
String[172.7359,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387207]t
String[174.67462,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]o
String[178.55205,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.322281]r
String[58.912003,65.483 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=7.192993]D
String[87.536,73.099 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=7.577202]F
String[96.740005,73.099 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[101.29201,73.099 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.5137405]s
String[106.80601,73.099 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.5525436])
String[88.983,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]s
String[92.4699,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]e
String[96.347336,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]n
String[100.22477,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]s
String[103.71167,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[107.5891,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
但是,我做了一个小的更改,看起来每个文本项都会调用
writeString
方法,我想我可以找到每个字符串的整体边框:

/**
 * Override the default functionality of PDFTextStripper.
 */
@Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException
{
    System.out.println("text string: "+string);
    for (TextPosition text : textPositions)
    {
        System.out.println( "String[" + text.getXDirAdj() + "," +
                text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale=" +
                text.getXScale() + " height=" + text.getHeightDir() + " space=" +
                text.getWidthOfSpace() + " width=" +
                text.getWidthDirAdj() + "]" + text.getUnicode() );
    }
}

嗯,我找到了ApachePDFBox库,它包含一个名为的示例,它可以打印信息,但我不确定如何解释它,每个glyph有一个位置

> java -jar print_text_locations.jar blockdiagram_example.pdf
String[37.864998,13.939003 fs=4.9813 xscale=4.9813 height=2.49065 space=2.4906502 width=5.1197815]+
String[59.185997,13.662003 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=6.6450577]A
String[130.229,13.662003 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=6.64505]B
String[198.783,13.498001 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=7.192993]C
String[86.827,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=9.699257]H
String[97.449005,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[102.00201,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.5137405]s
String[107.51601,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536])
String[156.35,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=9.234192]G
String[165.58301,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[170.136,21.278 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.513733]s
String[175.65,21.278 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536])
String[12.797,29.332 fs=9.9626 xscale=9.9626 height=4.9813 space=4.9813004 width=5.7035875]u
String[38.711,27.432999 fs=4.9813 xscale=4.9813 height=3.4022279 space=2.4906502 width=5.39624]?
String[214.641,29.332 fs=9.9626 xscale=9.9626 height=4.9813 space=4.9813004 width=4.884659]y
String[85.109,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]c
String[88.5959,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[92.473335,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]n
String[96.35077,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387131]t
String[98.28948,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
String[100.611755,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[104.48919,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.5481873]l
String[106.03738,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.5481873]l
String[107.58556,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]e
String[111.463,41.419 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
String[155.67801,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]a
String[159.55544,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4868927]c
String[163.04233,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387207]t
String[164.98105,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]u
String[168.85847,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]a
String[172.7359,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=1.9387207]t
String[174.67462,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774261]o
String[178.55205,41.046 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.322281]r
String[58.912003,65.483 fs=9.9626 xscale=9.9626 height=6.1668496 space=2.769603 width=7.192993]D
String[87.536,73.099 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=7.577202]F
String[96.740005,73.099 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.552536](
String[101.29201,73.099 fs=11.9552 xscale=11.9552 height=5.9776 space=5.9776006 width=5.5137405]s
String[106.80601,73.099 fs=11.9552 xscale=11.9552 height=5.983578 space=5.9776006 width=4.5525436])
String[88.983,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]s
String[92.4699,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]e
String[96.347336,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]n
String[100.22477,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.4869003]s
String[103.71167,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=3.8774338]o
String[107.5891,91.978004 fs=6.9738 xscale=6.9738 height=4.3167825 space=1.9387167 width=2.3222733]r
但是,我做了一个小的更改,看起来每个文本项都会调用
writeString
方法,我想我可以找到每个字符串的整体边框:

/**
 * Override the default functionality of PDFTextStripper.
 */
@Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException
{
    System.out.println("text string: "+string);
    for (TextPosition text : textPositions)
    {
        System.out.println( "String[" + text.getXDirAdj() + "," +
                text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale=" +
                text.getXScale() + " height=" + text.getHeightDir() + " space=" +
                text.getWidthOfSpace() + " width=" +
                text.getWidthDirAdj() + "]" + text.getUnicode() );
    }
}

我能够将以下Python解决方案组合在一起,作为一个起点。它将pdf转换为png并输出相应的图像地图标记

它将输出dpi作为可选参数(默认值200),以便将边界框从默认的pdf dpi 72正确缩放到png:

从pdf2image导入从路径转换
从pdfminer.converter导入PDFPageAggregator
从pdfminer.layout导入LAParams,LTTextBox
从pdfminer.pdfinterp导入pdfpageexplorer
从pdfminer.pdfinterp导入PDFResourceManager
从pdfminer.pdfpage导入pdfpage
从标签导入单据,缩进
导入argparse
导入操作系统
def转换坐标(lobj,mb):
#将LTTextBox边界框转换为图像贴图区域边界框。
#
#每个LTTextBox的边界框指定为:
#
#x0:从页面左侧到框左边缘的距离
#y0:从页面底部到框的下边缘的距离
#x1:从页面左侧到方框右边缘的距离
#y1:从页面底部到框的上边缘的距离
#
#所以y坐标从图像的底部开始。但是有了图像地图
#面积,y坐标从图像顶部开始,所以这里我们减去
#边界框的y轴值来自总高度。
返回[lobj.x0,mb[3]-lobj.y1,lobj.x1,mb[3]-lobj.y0]
def get_图像映射(d):
doc,tag,text=doc().tagtext()
带标签(“地图”,name=“地图”):
对于d.项()中的k,v:
doc.stag(“area”,shape=“rect”,coords=”,“.join(v),href=”,alt=k)
返回缩进(doc.getvalue())
def get_bboxes(pdf,dpi):
fp=开放(pdf,“rb”)
rsrcmgr=PDFResourceManager()
device=PDFPageAggregator(rsrcmgr,laparams=laparams())
解释器=PDFPAGE解释器(rsrcmgr,设备)
页面=列表(PDFPage.get_页面(fp))[0]
解释器。处理页面(第页)
布局=设备。获取_结果()
#PDFminer基于72的dpi报告边界框。我找不到办法
#为了改变这一点,我用dpi/72来缩放每个坐标
刻度=dpi/72.0
返回{
lobj.get_text().strip():[
转换坐标中x的str(int(x*scale))(lobj,page.mediabox)
]
用于布局中的lobj
如果isinstance(lobj,LTTextBox)
}
def main():
parser=argparse.ArgumentParser()
parser.add_参数(“pdf”)
add_参数(“--dpi”,type=int,default=200)
args=parser.parse_args()
页面=列表(从路径(args.pdf,args.dpi)转换)[0]
save(f“{os.path.splitext(args.pdf)[0]}.png”,“png”)
打印(get_imagemap(get_bboxes(args.pdf,args.dpi)))
如果名称=“\uuuuu main\uuuuuuuu”:
main()
示例结果:


我能够将以下Python解决方案组合在一起,作为一个起点。它将pdf转换为png并输出相应的图像地图标记

它将输出dpi作为可选参数(默认值200),以便将边界框从默认的pdf dpi 72正确缩放到png:

从pdf2image导入从路径转换
从pdfminer.converter导入PDFPageAggregator
从pdfminer.layout导入LAParams,LTTextBox
从pdfminer.pdfinterp导入pdfpageexplorer
从pdfminer.pdfinterp导入PDFResourceManager
从pdfminer.pdfpage导入pdfpage
从标签导入单据,缩进
导入argparse
导入操作系统
def转换坐标(lobj,mb):
#将LTTextBox边界框转换为图像贴图区域边界框。
#
#每个LTTextBox的边界框指定为:
#
#x0:从页面左侧到页面左边缘的距离