К сожалению, пример PDF не помечен. Таким образом, в противном случае необходимо попытаться связать текст заголовка и изображение либо путем анализа местоположения относительно друг друга, либо путем использования шаблона в потоках контента.
В данном случае анализ местоположения относительно друг друга возможен, поскольку заголовок всегда (хотя бы частично) рисуется на соответствующем изображении или является текстом прямо под ним. Таким образом, можно в первом проходе извлечь текст с позицией со страницы, а во втором - изображения, одновременно ища заголовок в ранее извлеченном тексте в области изображения или прямо под ним. В качестве альтернативы можно сначала извлечь изображения с положением и размером, а затем извлечь текст в этих областях.
Но в потоках контента также есть определенный шаблон: титр всегда рисуется в одной инструкции рисования текста сразу после рисования соответствующего изображения. Таким образом, можно также пойти вперед и извлечь за один проход изображения и следующий нарисованный текст как связанный заголовок.
Любой подход может быть реализован с использованием API синтаксического анализатора iText. Например, в случае последнего подхода следующее: сначала реализуется слушатель рендеринга, который ведет себя так, как описано, т.е. сохраняет изображения и следующий текст:
internal class ImageWithTitleRenderListener : IRenderListener
{
int imageNumber = 0;
String format;
bool expectingTitle = false;
public ImageWithTitleRenderListener(String format)
{
this.format = format;
}
public void BeginTextBlock()
{ }
public void EndTextBlock()
{ }
public void RenderText(TextRenderInfo renderInfo)
{
if (expectingTitle)
{
expectingTitle = false;
File.WriteAllText(string.Format(format, imageNumber, "txt"), renderInfo.GetText());
}
}
public void RenderImage(ImageRenderInfo renderInfo)
{
imageNumber++;
expectingTitle = true;
PdfImageObject imageObject = renderInfo.GetImage();
if (imageObject == null)
{
Console.WriteLine("Image {0} could not be read.", imageNumber);
}
else
{
File.WriteAllBytes(string.Format(format, imageNumber, imageObject.GetFileType()), imageObject.GetImageAsBytes());
}
}
}
Затем выполняется синтаксический анализ страниц документа с использованием этого обработчика визуализации:
using (PdfReader reader = new PdfReader(@"EVERMOTION ARCHMODELS VOL.78.pdf"))
{
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
ImageWithTitleRenderListener listener = new ImageWithTitleRenderListener(@"EVERMOTION ARCHMODELS VOL.78-{0:D3}.{1}");
for (var i = 1; i <= reader.NumberOfPages; i++)
{
parser.ProcessContent(i, listener);
}
}