从PDF创建图像(PNG或JPEG)以及图像中文本的HTML图像图? [英] Creating image (PNG or JPEG) from PDF along with HTML image maps of text in the image?

查看:84
本文介绍了从PDF创建图像(PNG或JPEG)以及图像中文本的HTML图像图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am documenting a system I maintain. This documentation contains a diagram I created in TeX/TikZ which gets rendered to a PDF file. Then I convert the PDF file to an image file (PNG via imagemagick), and include it in my HTML documentation. Works great.

现在,我想为该图像创建一个图像地图,这样我就可以添加超链接/鼠标悬停/等.这是我希望根据系统中的更改定期更新的图像,因此,我希望在可能的情况下自动执行此过程.

Now I would like to create an image map for the image, so that I can add hyperlinks/mouseovers/etc. This is an image that I expect to update periodically based on changes in my system, so I would like to automate this process if possible.

当PDF文件呈现为PNG时,是否可以使用软件库或工具自动创建PDF文件中各种文本内容的图像映射?

以下是我创建的要点:

在这种情况下,我想通过在PDF中找到它们的边界框来将各种文本字符串中的一些变成超链接:

In this case I would like to turn some of the various text strings into hyperlinks by locating their bounding box in the PDF:

  • controller
  • actuator
  • sensor
  • A
  • B
  • C
  • D
  • u
  • y
  • F(s)
  • G(s)
  • H(s)
  • controller
  • actuator
  • sensor
  • A
  • B
  • C
  • D
  • u
  • y
  • F(s)
  • G(s)
  • H(s)

(它们都是PDF文件中的文本内容;我可以在Acrobat Reader中选择其中任何一个的文本,然后复制+粘贴到我的文本编辑器中.)

(They are all text content in the PDF file; I can select the text of any of them in Acrobat Reader and copy + paste into my text editor.)

有没有办法做到这一点?

Is there a way to do this?

推荐答案

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

I was able to put together the following Python solution that could serve as a starting point. It converts the pdf to a png and outputs corresponding image map markup.

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

It takes output dpi as an optional argument (default 200) in order to properly scale the bounding boxes onto the png from the default pdf dpi of 72:

from pdf2image import convert_from_path
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBox
from pdfminer.pdfinterp import PDFPageInterpreter
from pdfminer.pdfinterp import PDFResourceManager
from pdfminer.pdfpage import PDFPage

from yattag import Doc, indent

import argparse
import os


def transform_coords(lobj, mb):

    # Transform LTTextBox bounding box to image map area bounding box.
    #
    # The bounding box of each LTTextBox is specified as:
    #
    # x0: the distance from the left of the page to the left edge of the box
    # y0: the distance from the bottom of the page to the lower edge of the box
    # x1: the distance from the left of the page to the right edge of the box
    # y1: the distance from the bottom of the page to the upper edge of the box
    #
    # So the y coordinates start from the bottom of the image. But with image map
    # areas, y coordinates start from the top of the image, so here we subtract
    # the bounding box's y-axis values from the total height.

    return [lobj.x0, mb[3] - lobj.y1, lobj.x1, mb[3] - lobj.y0]


def get_imagemap(d):
    doc, tag, text = Doc().tagtext()
    with tag("map", name="map"):
        for k, v in d.items():
            doc.stag("area", shape="rect", coords=",".join(v), href="", alt=k)
    return indent(doc.getvalue())


def get_bboxes(pdf, dpi):
    fp = open(pdf, "rb")
    rsrcmgr = PDFResourceManager()
    device = PDFPageAggregator(rsrcmgr, laparams=LAParams())
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    page = list(PDFPage.get_pages(fp))[0]

    interpreter.process_page(page)
    layout = device.get_result()

    # PDFminer reports bounding boxes based on a dpi of 72. I could not find a way
    # to change this, so instead I scale each coordinate by multiplying by dpi/72
    scale = dpi / 72.0

    return {
        lobj.get_text().strip(): [
            str(int(x * scale)) for x in transform_coords(lobj, page.mediabox)
        ]
        for lobj in layout
        if isinstance(lobj, LTTextBox)
    }


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("pdf")
    parser.add_argument("--dpi", type=int, default=200)

    args = parser.parse_args()

    page = list(convert_from_path(args.pdf, args.dpi))[0]
    page.save(f"{os.path.splitext(args.pdf)[0]}.png", "PNG")

    print(get_imagemap(get_bboxes(args.pdf, args.dpi)))


if __name__ == "__main__":
    main()

示例结果:

<img src="https://i.stack.imgur.com/aXWMc.png" usemap="#map">
<map name="map">
  <area shape="rect" coords="361,8,380,43" href="#" alt="B" />
  <area shape="rect" coords="434,31,500,64" href="#" alt="G(s)" />
  <area shape="rect" coords="432,93,502,117" href="#" alt="actuator" />
  <area shape="rect" coords="552,8,572,42" href="#" alt="C" />
  <area shape="rect" coords="596,58,609,86" href="#" alt="y" />
  <area shape="rect" coords="105,26,119,40" href="#" alt="+" />
  <area shape="rect" coords="107,54,122,78" href="#" alt="−" />
  <area shape="rect" coords="35,58,51,86" href="#" alt="u" />
  <area shape="rect" coords="164,8,182,43" href="#" alt="A" />
  <area shape="rect" coords="163,152,183,187" href="#" alt="D" />
  <area shape="rect" coords="241,31,311,64" href="#" alt="H(s)" />
  <area shape="rect" coords="236,94,316,118" href="#" alt="controller" />
  <area shape="rect" coords="243,175,309,208" href="#" alt="F (s)" />
  <area shape="rect" coords="247,234,305,258" href="#" alt="sensor" />
</map>

这篇关于从PDF创建图像(PNG或JPEG)以及图像中文本的HTML图像图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆