Itext 段落内图像的提取
我正在构建一个应用程序,其中我需要解析一个由系统生成的pdf,并使用解析后的信息填充我的应用程序数据库列,但不幸的是,我正在处理的pdf结构有一个名为comments的列,该列包含文本和图像。我找到了从pdf中分别读取图像和文本的方法,但我的最终目标是在解析内容中的图像位置添加一个类似{2}的占位符,并且每当我的解析器(应用程序代码)出现时解析这一行,系统将在该区域中呈现适当的图像,该图像也存储在我的应用程序中的一个单独的表中。 请帮我解决这个问题Itext 段落内图像的提取,itext,Itext,我正在构建一个应用程序,其中我需要解析一个由系统生成的pdf,并使用解析后的信息填充我的应用程序数据库列,但不幸的是,我正在处理的pdf结构有一个名为comments的列,该列包含文本和图像。我找到了从pdf中分别读取图像和文本的方法,但我的最终目标是在解析内容中的图像位置添加一个类似{2}的占位符,并且每当我的解析器(应用程序代码)出现时解析这一行,系统将在该区域中呈现适当的图像,该图像也存储在我的应用程序中的一个单独的表中。 请帮我解决这个问题 提前感谢。如评论中所述,解决方案基本上是使用自
提前感谢。如评论中所述,解决方案基本上是使用自定义文本提取策略在图像坐标处插入“[2]”文本块 代码 例如,您可以这样扩展
LocationTextExtractionStrategy
:
class SimpleMixedExtractionStrategy extends LocationTextExtractionStrategy
{
SimpleMixedExtractionStrategy(File outputPath, String name)
{
this.outputPath = outputPath;
this.name = name;
}
@Override
public void renderImage(final ImageRenderInfo renderInfo)
{
try
{
PdfImageObject image = renderInfo.getImage();
if (image == null) return;
int number = counter++;
final String filename = String.format("%s-%s.%s", name, number, image.getFileType());
Files.write(new File(outputPath, filename).toPath(), image.getImageAsBytes());
LineSegment segment = UNIT_LINE.transformBy(renderInfo.getImageCTM());
TextChunk location = new TextChunk("[" + filename + "]", segment.getStartPoint(), segment.getEndPoint(), 0f);
Field field = LocationTextExtractionStrategy.class.getDeclaredField("locationalResult");
field.setAccessible(true);
List<TextChunk> locationalResult = (List<TextChunk>) field.get(this);
locationalResult.add(location);
}
catch (IOException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ioe)
{
ioe.printStackTrace();
}
}
final File outputPath;
final String name;
int counter = 0;
final static LineSegment UNIT_LINE = new LineSegment(new Vector(0, 0, 1) , new Vector(1, 0, 1));
}
@Test
public void testSimpleMixedExtraction() throws IOException
{
InputStream resourceStream = getClass().getResourceAsStream("book-of-vaadin-page14.pdf");
try
{
PdfReader reader = new PdfReader(resourceStream);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
SimpleMixedExtractionStrategy listener = new SimpleMixedExtractionStrategy(OUTPUT_PATH, "book-of-vaadin-page14");
parser.processContent(1, listener);
Files.write(new File(OUTPUT_PATH, "book-of-vaadin-page14.txt").toPath(), listener.getResultantText().getBytes());
}
finally
{
if (resourceStream != null)
resourceStream.close();
}
}
例如,对于我的测试文件(包含《瓦丁书》第14页):
你得到这个文本了吗
Getting Started with Vaadin
• A version of Book of Vaadin that you can browse in the Eclipse Help system.
You can install the plugin as follows:
1. Start Eclipse.
2. Select Help Software Updates....
3. Select the Available Software tab.
4. Add the Vaadin plugin update site by clicking Add Site....
[book-of-vaadin-page14-0.png]
Enter the URL of the Vaadin Update Site: http://vaadin.com/eclipse and click OK. The
Vaadin site should now appear in the Software Updates window.
5. Select all the Vaadin plugins in the tree.
[book-of-vaadin-page14-1.png]
Finally, click Install.
Detailed and up-to-date installation instructions for the Eclipse plugin can be found at http://vaad-
in.com/eclipse.
Updating the Vaadin Plugin
If you have automatic updates enabled in Eclipse (see Window Preferences Install/Update
Automatic Updates), the Vaadin plugin will be updated automatically along with other plugins.
Otherwise, you can update the Vaadin plugin (there are actually multiple plugins) manually as
follows:
1. Select Help Software Updates..., the Software Updates and Add-ons window will
open.
2. Select the Installed Software tab.
14 Vaadin Plugin for Eclipse
和两张图片book-of-vaadin-page14-0.png
和book-of-vaadin-page14-1.png
在输出路径中
改进
正如在评论中已经提到的,此解决方案适用于图像上下都有文本但既不左也不右的简单情况
如果左侧和/或右侧也有文本,则问题在于上面的代码将LineSegment
计算为图像的底线,但文本策略通常与位于底线之上的文本基线一起工作
但在这种情况下,我们首先必须决定文本中标记的位置。既然决定了这一点,就可以修改上面的源代码。因为您没有显示代码,所以很难说您需要修改什么。基本上使用自定义的文本提取策略在图像坐标处插入“[2]”文本块。@mkl很抱歉,我们尚未开始执行代码,但我们仍在分析是否可以使用itext执行此操作。正如你所说,我经历了文本提取策略我的需要是这样的评论部分将像“图形区域覆盖325公里…”其中将包含pdf中的图像,因此使用此文本提取策略,我是否可以这样做“图形区域覆盖325公里{2}…”其中2将指向存储图像的唯一区域(简单地说是数据库或文件系统)。这听起来像是通过一些额外的编程(编写渲染接口的子类)就可以实现的。@BrunoLowagie我也这么认为。只需注意将图像与周围文本的基线正确关联(如果图像是按直线绘制的)。但是,如果文字比图像比文字更重要,这应该很容易。是的,在插入(X)时决定要考虑哪个坐标将是一个设计决策。一个可以使用底部y坐标,顶部y坐标,中间的东西…这取决于实现应用程序的人员,基于图像的性质。感谢您的回答,这是我想要的应用程序,我尝试了这段代码,但您能告诉我在上述解决方案中,单位线是什么意思吗?我以为这是一种方法,但在itext库中找不到它?单位线是什么意思-哦,对不起,忘了抄了。这是从(0,0)到(0,1)的常数行,
SimpleMixedExtractionStrategy
中的常数。我马上编辑我的答案。