Skip to content
Image docs0.3

Ktor OCR API workshop

Latest stable Based on Image release 0.3.0

Runnable example

This Ktor 3 workshop accepts a streamed multipart image, parses Tesseract language codes, calls an injectable OcrEngine, and maps validation and native-runtime failures to stable JSON responses. Its tests run without a host Tesseract installation.

Use it when adding OCR to a Ktor service, learning how to isolate native dependencies behind an interface, or comparing Ktor wiring with the Spring Boot OCR workshop.

The example is not published. Select one bluetape4k-dependencies version for the application and consume bluetape4k-images-ocr; do not manage an independent OCR-module version.

  • Multipart input is streamed and limited by maxInputBytes before decoding.
  • eng+kor, eng,kor, and whitespace-separated values become a language list.
  • KtorOcrService depends on OcrEngine; production uses TesseractOcrEngine, tests inject a fake.
  • Invalid requests become 400 bad_request; OcrException becomes 503 ocr_unavailable.

JDK 21+ is sufficient for tests. Real OCR also requires Tesseract and the requested traineddata packages.

Terminal window
brew install tesseract tesseract-lang
export EXAMPLE_OCR_TESSDATA_PATH=/opt/homebrew/share/tessdata
./gradlew :ktor-ocr-api:run
Terminal window
curl -F "file=@sample-ko.png;type=image/png" \
"http://localhost:8080/api/ocr?languages=eng+kor"

The response contains text, normalized languages, and characterCount.

TaskRelease API
Configure route/runtimeKtorOcrApiConfig
Install endpointconfigureKtorOcrApi(config, ocrEngine)
Decode and recognizeimmutableImageOf(bytes).suspendExtractText(...)
Health checkGET /ready
OCR requestPOST /api/ocr?languages=eng+kor

Keep host-specific tessdata configuration outside the request, inject the OCR engine, cap bytes before image decoding, and map native availability separately from client validation. This keeps normal CI independent of Tesseract while preserving the production contract.

The workshop uses bluetape4k-images-ocr and core image decoding. Compare spring-boot-ocr-api to choose framework wiring without changing the OCR domain boundary.

Defaults: route /api/ocr, multipart field file, 10 MiB maximum, language eng, port 8080. PORT changes the port; EXAMPLE_OCR_TESSDATA_PATH supplies the host traineddata directory.

  • 400 bad_request: missing/wrong multipart field, empty upload, unsupported media type, invalid language list, or input over 10 MiB.
  • 503 ocr_unavailable: Tesseract, a traineddata package, or the native bridge is unavailable.
  • Empty/poor recognition: verify tesseract --list-langs, input resolution, contrast, orientation, and the requested language set.

Treat OCR as a bounded native service call. Add authentication, rate limiting, request queues, timeouts, and concurrency limits in the owning application. Log language and duration, not uploaded document contents.

Terminal window
./gradlew :ktor-ocr-api:test

Ktor testApplication verifies language parsing and tessdata propagation, wrong fields, unsupported content types, and the 503 native-failure mapping using a fake engine.

  1. Learn multipart route conventions in ktor-image-api.
  2. Run this workshop’s fake-engine tests before installing native OCR.
  3. Install Tesseract, verify languages, then send a real text-heavy image.
  4. Read the OCR module manual and compare the Spring Boot workshop.

The workshop does not include authentication, persistence, batch OCR, preprocessing policy, queues, or distributed admission control. OCR quality and supported languages depend on the host installation.

These diagrams are loaded directly from README assets published with the 0.3.0 release and pinned to its immutable commit. They describe this manual’s released structure and runtime flows, not later Snapshot changes. Select a preview to open the SVG at the same release commit.

Ktor OCR API Architecture

Release README: examples/ktor-ocr-api/README.md

Ktor OCR API Scenario

Release README: examples/ktor-ocr-api/README.md

Ktor OCR API Sequence

Release README: examples/ktor-ocr-api/README.md