gpt4 book ai didi

pdf - 将 PDF 文本转换为轮廓?

转载 作者:行者123 更新时间:2023-12-02 11:11:11 57 4
gpt4 key购买 nike

有人知道如何对 PDF 文档中的文本进行矢量化吗?也就是说,我希望每个字母都是一个形状/轮廓,没有任何文字内容。我使用的是 Linux 系统,首选开源或非 Windows 解决方案。

上下文:我正在尝试编辑一些旧的 PDF,但我不再拥有这些字体。我想在 Inkscape 中执行此操作,但这会将所有字体替换为通用字体,而且几乎不可读。我还使用 pdf2psps2pdf 来回转换,但字体信息保留在那里。因此,当我将其加载到 Inkscape 中时,它看起来仍然很糟糕。

有什么想法吗?谢谢。

最佳答案

要实现这一目标,您必须:

  1. 将 PDF 拆分为单独的页面;
  2. 将 PDF 页面转换为 SVG;
  3. 编辑您想要的页面
  4. 重新组合页面

这个答案将省略第 3 步,因为它不可编程。

分割 PDF

如果您不希望以编程方式分割文档,现代的方法是使用 stapler 。在您最喜欢的 shell 中:

stapler burst file.pdf

将生成 {file_1.pdf,...,file_N.pdf},其中 1...N 是 PDF 页面。订书机本身使用PyPDF2分割PDF文件的代码并不复杂。以下函数分割文件并将各个页面保存在当前目录中。 (无耻地从 commands.py 文件复制)

import math
import os
from PyPDF2 import PdfFileWriter, PdfFileReader

def split(filename):
with open(filename) as inputfp:
inputpdf = PdfFileReader(inputfp)

base, ext = os.path.splitext(os.path.basename(filename))

# Prefix the output template with zeros so that ordering is preserved
# (page 10 after page 09)
output_template = ''.join([
base,
'_',
'%0',
str(math.ceil(math.log10(inputpdf.getNumPages()))),
'd',
ext
])

for page in range(inputpdf.getNumPages()):
outputpdf = PdfFileWriter()
outputpdf.addPage(inputpdf.getPage(page))

outputname = output_template % (page + 1)

with open(outputname, 'wb') as fp:
outputpdf.write(fp)

将各个页面转换为 SVG

现在要将 PDF 转换为可编辑文件,我可能会使用 pdf2svg .

pdf2svg input.pdf output.svg

如果我们看一下 pdf2svg.c文件中,我们可以看到代码原则上并没有那么复杂(假设输入文件名在 filename 变量中,输出文件名在 outputname 变量中)。下面是一个 Python 中的最小工作示例。它需要 pycairopypoppler图书馆:

import os

import cairo
import poppler

def convert(inputname, outputname):
# Convert the input file name to an URI to please poppler
uri = 'file://' + os.path.abspath(inputname)

pdffile = poppler.document_new_from_file(uri, None)

# We only have one page, since we split prior to converting. Get the page
page = pdffile.get_page(0)

# Get the page dimensions
width, height = page.get_size()

# Open the SVG file to write on
surface = cairo.SVGSurface(outputname, width, height)
context = cairo.Context(surface)

# Now we finally can render the PDF to SVG
page.render_for_printing(context)
context.show_page()

此时,您应该拥有一个 SVG,其中所有文本都已转换为路径,并且能够使用 Inkscape 进行编辑,而不会出现渲染问题。

结合步骤 1 和 2

您可以在 for 循环中调用 pdf2svg 来执行此操作。但您需要事先知道页数。下面的代码计算页数并在一个步骤中完成转换。它只需要 pycairo 和 pypoppler:

import os, math

import cairo
import poppler

def convert(inputname, base=None):
'''Converts a multi-page PDF to multiple SVG files.

:param inputname: Name of the PDF to be converted
:param base: Base name for the SVG files (optional)
'''
if base is None:
base, ext = os.path.splitext(os.path.basename(inputname))

# Convert the input file name to an URI to please poppler
uri = 'file://' + os.path.abspath(inputname)

pdffile = poppler.document_new_from_file(uri, None)

pages = pdffile.get_n_pages()

# Prefix the output template with zeros so that ordering is preserved
# (page 10 after page 09)
output_template = ''.join([
base,
'_',
'%0',
str(math.ceil(math.log10(pages))),
'd',
'.svg'
])

# Iterate over all pages
for nthpage in range(pages):
page = pdffile.get_page(nthpage)

# Output file name based on template
outputname = output_template % (nthpage + 1)

# Get the page dimensions
width, height = page.get_size()

# Open the SVG file to write on
surface = cairo.SVGSurface(outputname, width, height)
context = cairo.Context(surface)

# Now we finally can render the PDF to SVG
page.render_for_printing(context)
context.show_page()

# Free some memory
surface.finish()

将 SVG 组装成单个 PDF

要重新组装,您可以使用 inkscape/订书机对手动转换文件。但编写执行此操作的代码并不难。下面的代码使用 rsvg 和 cairo。要从 SVG 进行转换并将所有内容合并到一个 PDF 中:

import rsvg
import cairo

def convert_merge(inputfiles, outputname):
# We have to create a PDF surface and inform a size. The size is
# irrelevant, though, as we will define the sizes of each page
# individually.
outputsurface = cairo.PDFSurface(outputname, 1, 1)
outputcontext = cairo.Context(outputsurface)

for inputfile in inputfiles:
# Open the SVG
svg = rsvg.Handle(file=inputfile)

# Set the size of the page itself
outputsurface.set_size(svg.props.width, svg.props.height)

# Draw on the PDF
svg.render_cairo(outputcontext)

# Finish the page and start a new one
outputcontext.show_page()

# Free some memory
outputsurface.finish()

PS:应该可以使用命令pdftocairo,但它似乎没有调用render_for_printing(),这使得输出的SVG保持字体信息.

关于pdf - 将 PDF 文本转换为轮廓?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26855026/

57 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com