This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 6e669506a49c Camel-Docling: Adding back and modify an old OCR I had 
for the original implementation
6e669506a49c is described below

commit 6e669506a49c21485249aafba083d70be3f9237e
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Jan 22 15:19:39 2026 +0100

    Camel-Docling: Adding back and modify an old OCR I had for the original 
implementation
    
    Signed-off-by: Andrea Cosentino <[email protected]>
---
 .../docling/integration/OcrExtractionIT.java       | 304 +++++++++++++++++++++
 1 file changed, 304 insertions(+)

diff --git 
a/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
new file mode 100644
index 000000000000..7bf10f275307
--- /dev/null
+++ 
b/components/camel-ai/camel-docling/src/test/java/org/apache/camel/component/docling/integration/OcrExtractionIT.java
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.docling.integration;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import javax.imageio.ImageIO;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.docling.DoclingComponent;
+import org.apache.camel.component.docling.DoclingConfiguration;
+import org.apache.camel.test.infra.docling.services.DoclingService;
+import org.apache.camel.test.infra.docling.services.DoclingServiceFactory;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * Integration test for OCR text extraction from images using Docling.
+ *
+ * This test demonstrates how to use Docling's OCR capabilities to extract 
text from images containing text content.
+ */
+@DisabledIfSystemProperty(named = "ci.env.name", matches = ".*", 
disabledReason = "Too much resources on GitHub Actions")
+public class OcrExtractionIT extends CamelTestSupport {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(OcrExtractionIT.class);
+
+    private static final String TEST_TEXT_LINE1 = "Hello World";
+    private static final String TEST_TEXT_LINE2 = "Apache Camel Integration";
+    private static final String TEST_TEXT_LINE3 = "OCR Test Document";
+
+    @RegisterExtension
+    static DoclingService doclingService = 
DoclingServiceFactory.createService();
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        DoclingComponent docling = context.getComponent("docling", 
DoclingComponent.class);
+        DoclingConfiguration conf = new DoclingConfiguration();
+        conf.setUseDoclingServe(true);
+        conf.setDoclingServeUrl(doclingService.doclingServerUrl());
+        conf.setEnableOCR(true);
+        conf.setOcrLanguage("en");
+        docling.setConfiguration(conf);
+
+        LOG.info("Testing Docling OCR at: {}", 
doclingService.doclingServerUrl());
+
+        return context;
+    }
+
+    @Test
+    public void testOcrTextExtractionFromImage() throws Exception {
+        Path testImage = createTestImageWithText();
+
+        LOG.info("Created test image at: {}", testImage);
+
+        String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "OCR result should not be null");
+        assertTrue(result.length() > 0, "OCR result should not be empty");
+
+        LOG.info("OCR extraction result:\n{}", result);
+
+        // Verify that at least some of the expected text was extracted
+        // Note: OCR may not be 100% accurate, so we check for partial matches
+        String resultLower = result.toLowerCase();
+        boolean foundHello = resultLower.contains("hello") || 
resultLower.contains("world");
+        boolean foundApache = resultLower.contains("apache") || 
resultLower.contains("camel");
+        boolean foundOcr = resultLower.contains("ocr") || 
resultLower.contains("test");
+
+        assertTrue(foundHello || foundApache || foundOcr,
+                "OCR should extract at least some of the expected text. Got: " 
+ result);
+
+        LOG.info("Successfully extracted text from image using OCR");
+    }
+
+    @Test
+    public void testOcrMarkdownConversionFromImage() throws Exception {
+        Path testImage = createTestImageWithText();
+
+        String result = template.requestBody("direct:ocr-convert-markdown", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "Markdown result should not be null");
+        assertTrue(result.length() > 0, "Markdown result should not be empty");
+
+        LOG.info("OCR Markdown conversion result:\n{}", result);
+        LOG.info("Successfully converted image to Markdown using OCR");
+    }
+
+    @Test
+    public void testOcrJsonConversionFromImage() throws Exception {
+        Path testImage = createTestImageWithText();
+
+        String result = template.requestBody("direct:ocr-convert-json", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "JSON result should not be null");
+        assertTrue(result.length() > 0, "JSON result should not be empty");
+        assertTrue(result.contains("{") || result.contains("["), "Result 
should be valid JSON");
+
+        LOG.info("OCR JSON conversion result:\n{}", result);
+        LOG.info("Successfully converted image to JSON using OCR");
+    }
+
+    @Test
+    public void testOcrWithAsyncMode() throws Exception {
+        Path testImage = createTestImageWithText();
+
+        String result = template.requestBody("direct:ocr-async-extract", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "Async OCR result should not be null");
+        assertTrue(result.length() > 0, "Async OCR result should not be 
empty");
+
+        LOG.info("Async OCR extraction result:\n{}", result);
+        LOG.info("Successfully extracted text from image using async OCR");
+    }
+
+    @Test
+    public void testOcrFromPngImage() throws Exception {
+        Path testImage = createTestPngImage();
+
+        String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "OCR result from PNG should not be null");
+        assertTrue(result.length() > 0, "OCR result from PNG should not be 
empty");
+
+        LOG.info("OCR extraction from PNG result:\n{}", result);
+        LOG.info("Successfully extracted text from PNG image using OCR");
+    }
+
+    @Test
+    public void testOcrWithMultipleTextBlocks() throws Exception {
+        Path testImage = createImageWithMultipleTextBlocks();
+
+        String result = template.requestBody("direct:ocr-extract-text", 
testImage.toString(), String.class);
+
+        assertNotNull(result, "OCR result should not be null");
+        assertTrue(result.length() > 0, "OCR result should not be empty");
+
+        LOG.info("OCR extraction with multiple text blocks result:\n{}", 
result);
+        LOG.info("Successfully extracted text from image with multiple text 
blocks");
+    }
+
+    /**
+     * Creates a test image with clear, readable text for OCR testing.
+     */
+    private Path createTestImageWithText() throws Exception {
+        int width = 800;
+        int height = 400;
+
+        BufferedImage image = new BufferedImage(width, height, 
BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = image.createGraphics();
+
+        // Set rendering hints for better text quality
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, 
RenderingHints.VALUE_RENDER_QUALITY);
+
+        // Fill background with white
+        g2d.setColor(Color.WHITE);
+        g2d.fillRect(0, 0, width, height);
+
+        // Draw text in black with a large, clear font
+        g2d.setColor(Color.BLACK);
+        g2d.setFont(new Font("SansSerif", Font.BOLD, 48));
+
+        // Draw multiple lines of text
+        g2d.drawString(TEST_TEXT_LINE1, 50, 100);
+        g2d.drawString(TEST_TEXT_LINE2, 50, 200);
+        g2d.drawString(TEST_TEXT_LINE3, 50, 300);
+
+        g2d.dispose();
+
+        // Save as JPEG
+        Path tempFile = Files.createTempFile("docling-ocr-test", ".jpg");
+        ImageIO.write(image, "jpg", tempFile.toFile());
+
+        return tempFile;
+    }
+
+    /**
+     * Creates a PNG test image with text.
+     */
+    private Path createTestPngImage() throws Exception {
+        int width = 600;
+        int height = 300;
+
+        BufferedImage image = new BufferedImage(width, height, 
BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = image.createGraphics();
+
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+        // White background
+        g2d.setColor(Color.WHITE);
+        g2d.fillRect(0, 0, width, height);
+
+        // Black text
+        g2d.setColor(Color.BLACK);
+        g2d.setFont(new Font("SansSerif", Font.PLAIN, 36));
+        g2d.drawString("PNG Image Test", 50, 80);
+        g2d.drawString("Docling OCR Processing", 50, 150);
+        g2d.drawString("Text Extraction Demo", 50, 220);
+
+        g2d.dispose();
+
+        Path tempFile = Files.createTempFile("docling-ocr-png-test", ".png");
+        ImageIO.write(image, "png", tempFile.toFile());
+
+        return tempFile;
+    }
+
+    /**
+     * Creates an image with multiple separate text blocks to test OCR layout 
detection.
+     */
+    private Path createImageWithMultipleTextBlocks() throws Exception {
+        int width = 800;
+        int height = 600;
+
+        BufferedImage image = new BufferedImage(width, height, 
BufferedImage.TYPE_INT_RGB);
+        Graphics2D g2d = image.createGraphics();
+
+        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+        // White background
+        g2d.setColor(Color.WHITE);
+        g2d.fillRect(0, 0, width, height);
+
+        g2d.setColor(Color.BLACK);
+
+        // Title block (large font)
+        g2d.setFont(new Font("SansSerif", Font.BOLD, 42));
+        g2d.drawString("Document Title", 50, 80);
+
+        // First paragraph block
+        g2d.setFont(new Font("SansSerif", Font.PLAIN, 24));
+        g2d.drawString("This is the first paragraph", 50, 160);
+        g2d.drawString("with multiple lines of text", 50, 195);
+
+        // Second paragraph block (different position)
+        g2d.drawString("Second paragraph starts here", 50, 280);
+        g2d.drawString("containing more information", 50, 315);
+
+        // Footer block
+        g2d.setFont(new Font("SansSerif", Font.ITALIC, 18));
+        g2d.drawString("Footer: Apache Camel Docling Component", 50, 550);
+
+        g2d.dispose();
+
+        Path tempFile = Files.createTempFile("docling-ocr-multiblock-test", 
".jpg");
+        ImageIO.write(image, "jpg", tempFile.toFile());
+
+        return tempFile;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // OCR text extraction route
+                from("direct:ocr-extract-text")
+                        
.to("docling:ocr?operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en");
+
+                // OCR to Markdown conversion
+                from("direct:ocr-convert-markdown")
+                        
.to("docling:ocr?operation=CONVERT_TO_MARKDOWN&enableOCR=true&ocrLanguage=en");
+
+                // OCR to JSON conversion
+                from("direct:ocr-convert-json")
+                        
.to("docling:ocr?operation=CONVERT_TO_JSON&enableOCR=true&ocrLanguage=en");
+
+                // OCR with async mode
+                from("direct:ocr-async-extract")
+                        
.to("docling:ocr?operation=EXTRACT_TEXT&enableOCR=true&ocrLanguage=en&useAsyncMode=true&asyncPollInterval=1000&asyncTimeout=180000");
+            }
+        };
+    }
+
+}

Reply via email to