Python Pdftron-使用与现有图元相同的样式创建新图元

Python Pdftron-使用与现有图元相同的样式创建新图元,python,pdf,pdftron,pdfnet,Python,Pdf,Pdftron,Pdfnet,我正在尝试使用软件创建PDF编辑原型 我已经成功地创建了一个界面,用户可以点击图像,从PDF创建,选择区域,并将显示一个文本输入,他/她可以在其中输入文本,这将取代PDF文件中的内容 现在替换部分的文本是有问题的。因为Python没有API文档(仅示例),所以我遵循Java/Android API文档 我现在在哪里。我有以下代码来找出用户选择的矩形中的元素。值x1,y1,x2,y2是基于前端用户选择的PDF坐标 rect = Rect(x1, y1, x2, y2) text = '' extr

我正在尝试使用软件创建PDF编辑原型

我已经成功地创建了一个界面,用户可以点击图像,从PDF创建,选择区域,并将显示一个文本输入,他/她可以在其中输入文本,这将取代PDF文件中的内容

现在替换部分的文本是有问题的。因为Python没有API文档(仅示例),所以我遵循Java/Android API文档

我现在在哪里。我有以下代码来找出用户选择的矩形中的元素。值
x1
y1
x2
y2
是基于前端用户选择的PDF坐标

rect = Rect(x1, y1, x2, y2)
text = ''
extractor = TextExtractor()
extractor.Begin(page)
line = extractor.GetFirstLine()
words = []
while line.IsValid():
    word = line.GetFirstWord()
    while word.IsValid():
        elRect = word.GetBBox()
        elRect.Normalize()
        if elRect.IntersectRect(elRect, rect):
            text += ' ' + word.GetString()
            words.append(word)
        word = word.GetNextWord()
    line = line.GetNextLine()
words
基本上是一个数组,我在其中存储稍后需要替换为新元素的内容

现在问题来了。我希望新元素具有与旧文本相同的样式和字体。 Api()告诉我使用

style = words[0].GetStyle()
给我单词的样式,我可以使用

font = style.GetFont()
文件:

但是返回的
font
属于
Obj
类,而不是
font

显然,用font创建新的文本元素需要
font
类的对象

因为

element = eb.CreateTextBegin(font, 10.0);
生成一个错误:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/alan/.virtualenvs/pdfprint/local/lib/python2.7/site-packages/PDFNetPython2.py", line 5056, in CreateTextBegin
    def CreateTextBegin(self, *args): return _PDFNetPython2.ElementBuilder_CreateTextBegin(self, *args)
NotImplementedError: Wrong number or type of arguments for overloaded function 'ElementBuilder_CreateTextBegin'.
  Possible C/C++ prototypes are:
    pdftron::PDF::ElementBuilder::CreateTextBegin(pdftron::PDF::Font,double)
    pdftron::PDF::ElementBuilder::CreateTextBegin()
但仍然坚持使用这些样式创建元素

/edit1

Edit2

我使用以下代码测试写入文件:

style = elements[0].GetStyle()
font = Font(style.GetFont())
fontsize = style.GetFontSize()
eb = ElementBuilder()
element = eb.CreateTextBegin(font, 10.0)
writer.WriteElement(element)
element = eb.CreateTextRun('My Name')
element.SetTextMatrix(10, 0, 0, 10, 100, 100)
gstate = element.GetGState()
gstate.SetTextRenderMode(GState.e_fill_text)
gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB())
gstate.SetStrokeColor(ColorPt(1, 1, 1))
element.UpdateTextMetrics()
writer.WriteElement(element)
writer.WriteElement(eb.CreateTextEnd())
writer.End()
from core.helpers import ensure_dir
ensure_dir(output_filename)
doc.Save(output_filename, SDFDoc.e_linearized)
doc.Close()
我不明白的是:

  • 如何从现有图元复制样式
  • 如何在文档中定位新元素
  • 为什么这个测试代码没有给我明显的结果。就我所见,新文件是由它创建的,它的任何地方都没有“我的名字”

  • /Edit2

    根据上面的代码,您似乎希望根据页面上第一个单词使用的字体样式(字体名称+颜色)向现有页面添加一些文本

    上述代码存在耦合问题。您正在设置笔划颜色而不是填充:

    gstate.SetTextRenderMode(GState.e_fill_text)
    gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
    gstate.SetStrokeColor(ColorPt(1, 1, 1))
    
    试一试

    主要问题很可能与字体处理有关。您正在劫持现有字体,并假设此字体使用“标准编码”。但是,此字体可能未使用标准编码。此外,现有PDF中的字体通常是子设置的(这意味着字体不包含完整的字形列表,而只包含文档中存在的字符引用)。因此,您可能会看到notdef或空白,而不是预期的文本。这里介绍了这一问题和其他一些问题:

    作为解决方案,您可以找到匹配的系统字体(例如,基于字体名称和其他属性)并创建新字体,而不是直接使用嵌入式字体。PDFNet提供了一种实用的方法

    此方法将创建Unicode字体,因此您应该使用eb.CreateUnicodeTextRun()而不是eb.CreateTextRun()


    或者,您可以使用AcroForm作为模板(请参见InteractiveForms示例),并使用pdfdoc.fattenanotations()以只读版本结束文档。

    我不能使用replacer,因为查看replacer代码时,它似乎希望在一个文本元素中找到完整的字符串。但在我的测试用例中,某些区域的pdf在不同的文本节点/元素中都有单个字母。在任何情况下,replacer代码都会运行,但无法产生任何结果,就像我发布的代码一样。现在关于字体-字体应该完全存在于文件中。但我会测试如果我加载自己的字体文件会发生什么。
    gstate.SetTextRenderMode(GState.e_fill_text)
    gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
    gstate.SetStrokeColor(ColorPt(1, 1, 1))
    
    gstate.SetTextRenderMode(GState.e_fill_text)
    gstate.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
    gstate.SetFillColor(ColorPt(1, 0, 0))  // hardcode to red … for testing purposes only