提取段落内的图像
Extraction of images present inside a paragraph
我正在构建一个应用程序,我需要在其中解析由系统生成的 pdf,并使用解析后的信息填充我的应用程序数据库列,但不幸的是,我正在处理的 pdf 结构有一个列称为评论,其中包含文本和图像。我找到了从 pdf 中单独读取图像和文本的方法,但我的最终目标是在解析内容中的图像位置添加一个类似 {2} 的占位符,每当我的解析器(应用程序代码)解析此行时系统将在该区域呈现适当的图像,该图像也存储在我的应用程序内的单独 table 中。
请帮我解决这个问题。
提前致谢。
正如评论中已经提到的,一种解决方案是基本上使用自定义的文本提取策略在图像的坐标处插入一个“[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));
}
(不幸的是,对于这种工作,LocationTextExtractionStrategy
的一些成员是私有的。因此,我使用了一些 Java 反射。或者你可以复制整个 class 并更改你的相应地复制。)
例子
使用该策略,您可以像这样提取混合内容:
@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();
}
}
例如对于我的测试文件(其中包含 Vaadin 之书的第 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
在 OUTPUT_PATH
.
要进行的改进
正如评论中已经提到的那样,此解决方案适用于图像上方 and/or 下方但既不左侧也不右侧的简单情况。
如果左边and/or右边也有文本,上面的代码计算LineSegment segment
作为图像的底线会出现问题但文本策略通常适用于文本的 基线 ,即底线上方。
但在这种情况下,首先必须决定无论如何都希望文本中的标记位于哪一行的哪个位置。决定后,可以改编上面的来源。
我正在构建一个应用程序,我需要在其中解析由系统生成的 pdf,并使用解析后的信息填充我的应用程序数据库列,但不幸的是,我正在处理的 pdf 结构有一个列称为评论,其中包含文本和图像。我找到了从 pdf 中单独读取图像和文本的方法,但我的最终目标是在解析内容中的图像位置添加一个类似 {2} 的占位符,每当我的解析器(应用程序代码)解析此行时系统将在该区域呈现适当的图像,该图像也存储在我的应用程序内的单独 table 中。 请帮我解决这个问题。
提前致谢。
正如评论中已经提到的,一种解决方案是基本上使用自定义的文本提取策略在图像的坐标处插入一个“[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));
}
(不幸的是,对于这种工作,LocationTextExtractionStrategy
的一些成员是私有的。因此,我使用了一些 Java 反射。或者你可以复制整个 class 并更改你的相应地复制。)
例子
使用该策略,您可以像这样提取混合内容:
@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();
}
}
例如对于我的测试文件(其中包含 Vaadin 之书的第 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
在 OUTPUT_PATH
.
要进行的改进
正如评论中已经提到的那样,此解决方案适用于图像上方 and/or 下方但既不左侧也不右侧的简单情况。
如果左边and/or右边也有文本,上面的代码计算LineSegment segment
作为图像的底线会出现问题但文本策略通常适用于文本的 基线 ,即底线上方。
但在这种情况下,首先必须决定无论如何都希望文本中的标记位于哪一行的哪个位置。决定后,可以改编上面的来源。