PdfTextExtractor.getTextFromPage(reader, pageNumber)
我很惊讶地发现输出中有几个错误,特别是所有字母d都变成了o。
那么iText中的文本提取到底是如何工作的呢?它是一种OCR技术吗?
我探究了一下的工作方式,但我无法弄清楚太多。例如,似乎只确定线条和空格的存在,而
TextRenderInfo
通过在GraphicsState
的font
字段上调用一些decode方法来提供文本,这就是我能做到的最好的了,否则会头痛难忍。那么我的问题是:哪个类应该被重写或者哪个参数应该被调整,以便告诉iText“嘿,你读错了所有的d!”?
编辑:
样例PDF可以在http://www.fpozzi.com/stampastopper/download/找到,文件名为0116_LR.pdf。 抱歉,无法分享直接链接。 这是一些用于文本提取的基本代码。
import java.io.File;
import java.io.IOException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
public class Import
{
public static void importFromPdf(final File pdfFile) throws IOException
{
PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
try
{
for (int i = 1; i <= reader.getNumberOfPages(); i++)
{
System.out.println(PdfTextExtractor.getTextFromPage(reader, i));
System.out.println("----------------------------------");
}
}
catch (IOException e)
{
throw e;
}
finally
{
reader.close();
}
}
public static void main(String[] args)
{
try
{
importFromPdf(new File("0116_LR.pdf"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
在@blagae和@mkl回答之后编辑
在开始使用iText之前,我尝试了从Apache PDFBox中提取文本(一个类似于iText的项目),但它存在相同的问题。
理解这些程序如何处理文本超出了我的热情范围,因此我编写了一个简单的方法来从原始页面内容中提取文本,即BT和ET标记之间的任何内容。
import java.io.File;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.itextpdf.text.io.RandomAccessSourceFactory;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.parser.ContentByteUtils;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
public class Import
{
private final static Pattern actualWordPattern = Pattern.compile("\\((.*?)\\)");
public static void importFromPdf(final File pdfFile) throws IOException
{
PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
Matcher matcher;
String line, extractedText;
boolean anyMatchFound;
try
{
for (int i = 1; i <= 16; i++)
{
byte[] contentBytes = ContentByteUtils.getContentBytesForPage(reader, i);
RandomAccessFileOrArray raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().createSource(contentBytes));
while ((line = raf.readLine()) != null && !line.equals("BT"));
extractedText = "";
while ((line = raf.readLine()) != null && !line.equals("ET"))
{
anyMatchFound = false;
matcher = actualWordPattern.matcher(line);
while (matcher.find())
{
anyMatchFound = true;
extractedText += matcher.group(1);
}
if (anyMatchFound)
extractedText += "\n";
}
System.out.println(extractedText);
System.out.println("+++++++++++++++++++++++++++");
String properlyExtractedText = PdfTextExtractor.getTextFromPage(reader, i);
System.out.println(properlyExtractedText);
System.out.println("---------------------------");
}
}
catch (IOException e)
{
throw e;
}
finally
{
reader.close();
}
}
public static void main(String[] args)
{
try
{
importFromPdf(new File("0116_LR.pdf"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
在我的情况下,字符看起来是正确的。然而单词甚至字母的顺序是混乱的,实际上非常混乱,因此这种方法也无法使用。
真正让我惊讶的是,到目前为止,我尝试过的所有从PDF中提取文本的方法,包括从Adobe Reader中复制/粘贴,都会出现问题。
我得出的结论是,获取一些可靠的文本提取的最可靠方法可能也是最出人意料的:使用优秀的OCR技术。
我现在正在尝试:
1)将PDF转换为图像(PDFBox非常擅长这样做 - 不要浪费时间尝试pdf-renderer)
2)对该图像进行OCR
我将在几天内发布结果。