介绍 早在2009年,我就写过一篇关于如何索引只支持图像的PDF文件的文章。当时的任务只是从iFilter中仅包含图像的PDF文件中提取文本,以便在WIndows环境中对这些文件进行索引。此次任务有些不一样——向PDF文件中添加文本信息。这种方法的好处是,文件能够经过标准的Adobe/Microsoft iFilters进行索引,但文本也能够经过可视化工具(Adobe Reader、Chome、Edge等)进行选择。 背景 我须要添加OCR信息到数千个PDF文件(存储在SQL服务器中)。我想建立一个脚本/实用程序,能够执行天天索引任何新的PDF文件,不包含可搜索文本。搜索了一段时间后,我找到了一个食谱: 使用ghostscript提取个别页面从PDF到图像(JPG)文件使用Tesseract提取OCR从图像存储提取的文本回PDF 用1 显然,自从我在2009年最后一次使用Tesseract以来,他们增长了一个新功能:图像和OCR文本将被导出为PDF文件。我认为你须要Tesseract版本4+。因此解决方案看起来很简单,接下来的批处理文件出如今20分钟内(见附件项目中的ocrate .bat): 隐藏,收缩,复制Codehtml
set gs="C:\Program Files\gs\gs9.52\bin\gswin64c.exe" set tesseract="\Program Files\Tesseract-OCR\tesseract.exe" if '%1'=='' goto :badParams if '%2'=='' goto :badParams mkdir %temp%\ocr\ set nm=%~n1 SETLOCAL ENABLEDELAYEDEXPANSION rem split pdf into multiple jpeg %gs% -dSAFER -dBATCH -dNOPAUSE -sDEVICE=jpeg -r300 -dTextAlphaBits=4 -o "%temp%\ocr\ocr_%nm%_%%04d.jpg" -f "%1" rem ocr each jpeg for %%i in (%temp%\ocr\ocr_%nm%_*.jpg) do %tesseract% -l eng "%%i" %%~pni pdf del %temp%\ocr\ocr_%nm%_*.jpg rem combine pdfs set ff=# for %%i in (%temp%\ocr\ocr_%nm%_*.pdf) do set ff=!ff! %%i set ff=%ff:#=% %gs% -dNOPAUSE -dQUIET -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -o "%2" %ff% del %temp%\ocr\ocr_%nm%_*.pdf goto :eof :badParams echo usage %0 pdf-In pdf-Out
如您所见,该脚本执行以下操做 使用GhostScript将单个页面提取到%temp%\ocr\####. JPG文件中,为每一个JPG文件运行Tesseract建立一个%temp%\ocr\####. PDF文件使用ghost script将全部PDF文件合并到输出文件中。 1的问题 很快,解决方案1的问题出如今大型PDF文件(10+页)上。 很是慢。但我想,既然它是做为后台进程运行,只对新文件,也许我能够接受这个。输出文件要比源文件大不少不少不少倍。成千上万的文件-成为了节目的终结者。 采起2 - HOCR2PDF 其余人也有一样的问题。进入HOCR2PDF (https://archive.codeplex.com/?p=hocrtopdf)。显然,Tesseract除了输出文本或PDF格式的OCR外,还能够输出HOCR文件——有效编码的HTML文件。因此任务稍微改变了一下 使用GhostScript将PDF文件拆分为多个JPGs使用tesseract将JPGs转换为HOCR文件解析HOCR文件使用PDF库(iTextShart)添加文本信息到输出的PDF Take 2 -问题 嗯,HOCR2PDF和我原来的脚本有相似的问题。它仍然很慢,文件仍然很大,尽管只有解决方案1的一半大小。 选3 -期末考试 因此我继续建立了我本身的项目。 在进行了一些故障排除和性能改进(好比启用压缩、为整个页面使用单一字体)以后,我发现大小膨胀归结为一次iTextShart函数调用 隐藏,复制Codegit
stamp.GetImportedPage(stamp.Reader, pg)
单是这通电话,每页就增长了3万美圆。惟一须要它的缘由是为了得到页面高度。将此调用替换为 隐藏,复制Codegithub
stamp.Reader.GetPageSizeWithRotation(pg).Height
尺寸膨胀消失了,令我惊讶的是,输出文件实际上比源文件更小(多是因为启用了压缩和删除未使用的对象)。 为了解决性能问题,我决定使用ThreadPool对每一个页面并发运行Tesseract。对于较大(10+页)的文件,性能的提高是很是显著的。 , 使用的代码 该项目包含一个带有公共方法OcrFile的PdfOcr类。用法以下: 隐藏,复制Codeweb
string txt = new PdfOcr().OcrFile(fileIn, fileOut);
这段代码将对fileIn pdf文件进行OCR,建立fileOut并返回OCR文本。该类可能须要经过改变/分配如下静态变量来定制: ,,,,GhostScript - GhostScript可执行文件的位置,,,Tesseract可执行文件的位置。,,,,将生成临时文件的文件夹。,,,tmpPrfx -全部临时文件的前缀 类和主程序一块儿存储在program .cs文件中,主程序有两个参数——源文件名和目标文件名。,,,,,,,,,,, ,,,,,,,,, 的兴趣点 https://github.com/UB-Mannheim/tesseract/wiki https://www.ghostscript.com/download/gsdnld.html - GhostScript二进制文件下载。https://archive.codeplex.com/?p=hocrtopdf - HOCR2PDF .NET实用程序 历史 最第一版本 本文转载于:http://www.diyabc.com/frontweb/news1636.html服务器