Tôi đang cố gắng thực hiện OCR trên pdf. Có 2 bước trong mã:
- Chuyển đổi tập tin pdf sang tập tin tiff
- Chuyển đổi tiff thành văn bản
Tôi đã sử dụng ghost4j cho bước đầu tiên, và sau đó tess4j cho bước thứ hai. tất cả đều hoạt động tốt, cho đến khi tôi bắt đầu chạy nó đa luồng, và sau đó xảy ra ngoại lệ lạ. Tôi đọc ở đây: https://sourceforge.net/p/tess4j/discussion/1202293/thread/44cc65c5/ rằng ghost4j không phù hợp với đa luồng, vì vậy tôi đã thay đổi bước đầu tiên để làm việc với PDFBox.
Vì vậy, bây giờ mã của tôi trông giống như:
PDDocument doc = PDDocument.load(this.bytes);
PDFRenderer pdfRenderer = new PDFRenderer(doc);
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "tiff", os);
os.flush();
os.close();
bufferedImage.flush();
Tôi đang cố chạy mã này với tệp pdf 800 kb và khi kiểm tra bộ nhớ sau
BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(0, 300);
nó tăng lên hơn 500 MB !! nếu tôi đang lưu BufferedImage này vào đĩa thì đầu ra có kích thước 1 MB ... vì vậy khi thử chạy mã này với 8 luồng, tôi cũng nhận được ngoại lệ kích thước heap java ...
Tôi đang thiếu gì ở đây? Tại sao tệp 1 MB dẫn đến tệp hình ảnh 500 MB? Tôi đã cố gắng chơi với DPI và giảm chất lượng nhưng tệp vẫn rất lớn ... Có thư viện nào khác có thể hiển thị pdf thành tiff không và tôi có thể thực thi 10 luồng mà không gặp vấn đề về bộ nhớ không?
Các bước để tái sản xuất:
- Tải xuống tệp sơ yếu lý lịch CEO Linkedin từ đây - https://gofile.io/?c=TtA7XQ
Tôi đã sử dụng mã này:
private static void test() throws IOException { printUsedMemory("App started..."); File file = new File("linkedinceoresume.pdf"); try (PDDocument doc = PDDocument.load(file)) { PDFRenderer pdfRenderer = new PDFRenderer(doc); printUsedMemory("Before"); for (int page = 0; page < 1; ++page) { BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(page, 76, ImageType.GRAY); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "tiff", os); os.flush(); os.close(); bufferedImage.flush(); } } finally { printUsedMemory("BufferedImage"); } } private static void printUsedMemory(String text) { long freeMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); long mb = freeMemory / 1000000; System.out.println(text + "....Used memory: " + mb + " MB"); }
và đầu ra là:
Ứng dụng bắt đầu ....... Bộ nhớ đã sử dụng: 42 MB
Trước .... Bộ nhớ đã sử dụng: 107 MB
BufferedImage .... Bộ nhớ đã sử dụng: 171 MB
Trong ví dụ này không phải là 500 MB, mà là pdf 70 kb, khi tôi cố gắng chỉ hiển thị một trang, bộ nhớ tăng lên khoảng 70 MB ... nó không tỷ lệ ...
BufferedImage
sau khi kết xuất?