利用tess4j把PDF转化为文字
前期准备
Java运行环境
在cmd输入:
JDK最好为8。
资源库
利用tess4j需要训练集和资源库,在这里我把资源库地址给写死了。
请把tessdata这个文件夹放在:E:/temp/
这个文件夹下面,没有则创建一个,仅仅手动操作这个便可以。
开始运行
在拿出Jar包,放在任意位置都可以,然后使用cmd 切换到目标地址下输入指令:
便可以运行了,然后打开:localhost:8888。访问或者使用。
原理
PDF操作
这里运用了maven,在pom文件下加入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>net.sourceforge.tess4j</groupId> <artifactId>tess4j</artifactId> <version>4.1.1</version> <exclusions> <exclusion> <groupId>com.sun.jna</groupId> <artifactId>jna</artifactId> </exclusion> </exclusions> </dependency>
|
这样便引入了对PDF的依赖,然后在后端的控制层加入:@RequestParam(“file”) MultipartFile file 去绑定所提交的PDF文件。
然后通过将pdf分解为图片,在使用tess4j去识别图片:
1 2 3 4 5 6 7 8 9 10
| PDDocument doc = PDDocument.load(multipartFileToFile(file)); PDFRenderer renderer = new PDFRenderer(doc); int pageCount = doc.getNumberOfPages(); for (int i = 0; i < pageCount; i++) { BufferedImage image = renderer.renderImageWithDPI(i, 144); String fn[]; fn=fileName.split("\\."); File my=new File(filePath + "\\" + fn + "_" + (i + 1) + "." + "jpg"); ImageIO.write(image, "jpg", my); tesspdf(my,i+1);
|
这里的tesspdf方法便是将图片转化为文字。
图像识别
在通过路劲获得了图片文件后,主要的操作方法是:
1
| tessreact.doOCR(imageFile);
|
它会读取相应的图片文件,然后进行转化,它的流程是:
1、先使用:public StringBuilder() { super(16);},对字符串进行构建和识别,防止空串。
2、再使用:AbstractStringBuilder(int capacity) { value = new char[capacity];},进行构建。
3、再对识别出的字符串进行拼串,为什么要这么做呢?那是因为有着:\\
,这样的特殊的转义字符。具体方法如下:
1 2 3 4 5 6 7 8 9
| public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
|
4、它会向tessOCR返回一个字符串表示收到,并开始构建:
1 2 3
| public String doOCR(File var1) throws TesseractException { return this.doOCR((File)var1, (Rectangle)null); }
|
5、从字符串的路径中找到图片:ImageIOHelper.getImageFile(var1);
6、然后通过一个方法获取到图像的格式:
1 2 3 4 5 6 7 8 9 10 11
| public static String getImageFileFormat(File var0) { String var1 = var0.getName(); String var2 = var1.substring(var1.lastIndexOf(46) + 1); if (var2.matches("(pbm|pgm|ppm)")) { var2 = "pnm"; } else if (var2.matches("(jp2|j2k|jpf|jpx|jpm)")) { var2 = "jpeg2000"; }
return var2; }
|
7、借助ImageIO这个类,对图像进行读取:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static Iterator<ImageReader> getImageReadersByFormatName(String formatName) { if (formatName == null) { throw new IllegalArgumentException("formatName == null!"); } Iterator iter; try { iter = theRegistry.getServiceProviders(ImageReaderSpi.class, new ContainsFilter(readerFormatNamesMethod, formatName), true); } catch (IllegalArgumentException e) { return Collections.emptyIterator(); } return new ImageReaderIterator(iter); }
|
8、可以从7看到,它返回的是迭代器,然后把这个迭代器的值转化为ImageReader
9、而这个ImageReader,已经拥有了对图片进行处理的能力,它会调用:readAll方法进行读取,主要方法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public IIOImage readAll(int imageIndex, ImageReadParam param) throws IOException { if (imageIndex < getMinIndex()) { throw new IndexOutOfBoundsException("imageIndex < getMinIndex()!"); }
BufferedImage im = read(imageIndex, param);
ArrayList thumbnails = null; int numThumbnails = getNumThumbnails(imageIndex); if (numThumbnails > 0) { thumbnails = new ArrayList(); for (int j = 0; j < numThumbnails; j++) { thumbnails.add(readThumbnail(imageIndex, j)); } }
IIOMetadata metadata = getImageMetadata(imageIndex); return new IIOImage(im, thumbnails, metadata); }
|
这个方法隐藏了很多细节,可以看到它返回的是IIOImage,而这个IIOImage,就是我们最终要得到的数据了。
10、然后使用doOCR方法进行字符串转化,也可看到这里填入的正是IIOImage类型的参数:
1 2 3 4 5 6 7 8 9 10 11 12
| private String doOCR(IIOImage var1, String var2, Rectangle var3, int var4) throws TesseractException { String var5 = "";
try { this.setImage(var1.getRenderedImage(), var3); var5 = this.getOCRText(var2, var4); } catch (IOException var7) { logger.warn(var7.getMessage(), var7); }
return var5; }
|
·