Android OCR Server приложение для распознавания текста с изображений через Google ML Kit.
- 📱 Android приложение с современным UI на Material Design 3
- 🚀 HTTP REST API для загрузки изображений и получения распознанного текста
- ⚡ WebSocket сервер для real-time стриминга результатов OCR
- 🔤 Поддержка языков: Английский (ML Kit), Русский (Tesseract OCR), Китайский, Японский, Корейский, Деванагари
- 🔒 Архитектура с заделом под аутентификацию
- 📊 Мониторинг запросов и активных WebSocket соединений
- 🔔 Foreground Service для стабильной работы в фоне
- Kotlin - язык программирования
- Google ML Kit - OCR движок для английского и других языков
- Tesseract OCR - специализированный движок для русского языка с высокой точностью
- NanoHTTPD - легковесный HTTP сервер
- Java-WebSocket - WebSocket сервер
- Material Design 3 - современный UI
- Coroutines - асинхронная обработка
- Android 7.0 (API 24) или выше
- Target SDK: Android 14 (API 34)
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH" && export JAVA_HOME="/opt/homebrew/opt/openjdk@17" && export ANDROID_HOME=/Users/core/Library/Android/sdk && ./gradlew assembleDebugadb install -s serial_number app-debug.apk- Откройте проект в Android Studio
- Синхронизируйте Gradle файлы
- Соберите и установите APK на устройство
./gradlew assembleDebug
adb install app/build/outputs/apk/debug/app-debug.apk- Откройте приложение на Android устройстве
- Нажмите кнопку "Start Server"
- Запишите IP адрес и порт сервера (отображается на экране)
- Убедитесь, что устройство и компьютер находятся в одной WiFi сети
Отправка файла:
curl -X POST http://192.168.1.10:8080/ocr \
-F "[email protected]"Отправка файла с указанием языка (русский):
curl -X POST http://192.168.1.10:8080/ocr \
-F "[email protected]" \
-F "language=rus"Поддерживаемые языковые коды:
eng- английский (ML Kit)rus- русский (Tesseract OCR - высокая точность для кириллицы)auto- автоопределениеchinese- китайскийjapanese- японскийkorean- корейскийdevanagari- деванагари
Отправка base64:
curl -X POST http://192.168.1.10:8080/ocr \
-H "Content-Type: application/json" \
-d '{"image": "data:image/jpeg;base64,/9j/4AAQ..."}'Ответ:
{
"success": true,
"text": "Распознанный текст",
"confidence": 0.95,
"language": "ru",
"processingTimeMs": 245,
"blocks": [
{
"text": "Распознанный текст",
"boundingBox": {
"left": 10,
"top": 20,
"right": 200,
"bottom": 50
}
}
]
}curl http://192.168.1.10:8080/statusОтвет:
{
"status": "running",
"uptime": 123456,
"requestCount": 42,
"port": 8080,
"ocrEngine": "Google ML Kit"
}curl http://192.168.1.10:8080/healthconst ws = new WebSocket('ws://192.168.1.10:8080/ws');
ws.onopen = () => {
console.log('Connected to OCR server');
// Отправка изображения для распознавания
ws.send(JSON.stringify({
type: 'ocr',
image: base64ImageData
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch(data.type) {
case 'status':
console.log('Status:', data.message);
break;
case 'progress':
console.log('Progress:', data.progress + '%');
break;
case 'result':
console.log('OCR Result:', data.text);
console.log('Language:', data.language);
console.log('Confidence:', data.confidence);
break;
case 'error':
console.error('Error:', data.error);
break;
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected from server');
};// Отправка ping
ws.send(JSON.stringify({ type: 'ping' }));
// Получение pong
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'pong') {
console.log('Server alive at', data.timestamp);
}
};Приложение имеет заготовку под аутентификацию через AuthMiddleware. Для включения:
- В коде активируйте middleware:
AuthMiddleware.setAuthEnabled(true)
AuthMiddleware.setAuthToken("your-secret-token")- При запросах добавляйте заголовок:
curl -X POST http://192.168.1.10:8080/ocr \
-H "Authorization: Bearer your-secret-token" \
-F "[email protected]"app/src/main/java/com/example/ocrserver/
├── MainActivity.kt # Главная Activity с UI
├── ocr/
│ ├── OcrEngine.kt # OCR движок на базе ML Kit
│ └── OcrResult.kt # Модели данных результатов
├── server/
│ ├── OcrHttpServer.kt # HTTP REST API сервер
│ ├── OcrWebSocketServer.kt # WebSocket сервер
│ └── RequestLog.kt # Модель логов запросов
├── service/
│ └── OcrServerService.kt # Foreground Service
├── auth/
│ └── AuthMiddleware.kt # Middleware аутентификации
├── utils/
│ ├── NetworkUtils.kt # Утилиты для работы с сетью
│ └── ImageUtils.kt # Утилиты для работы с изображениями
└── ui/
└── RequestLogAdapter.kt # Адаптер для списка логов
Приложение запрашивает следующие разрешения:
INTERNET- для работы HTTP/WebSocket сервераACCESS_NETWORK_STATE- для определения сетевого статусаFOREGROUND_SERVICE- для работы в фонеPOST_NOTIFICATIONS- для показа уведомлений (Android 13+)WAKE_LOCK- для предотвращения засыпания устройства
В проекте есть готовые тестовые клиенты для проверки OCR сервера.
# Проверка статуса сервера
python test_client.py --host 192.168.1.10 --port 8080 --mode status
# HTTP API (английский)
python test_client.py --host 192.168.1.10 --port 8080 --image photo.jpg --mode http
# HTTP API (русский) - Tesseract OCR
python test_client.py --host 192.168.1.10 --port 8080 --image photo.jpg --language rus --mode http
# WebSocket API (русский)
python test_client.py --host 192.168.1.10 --port 8080 --image photo.jpg --language rus --mode ws
# Тестирование обоих API сразу
python test_client.py --host 192.168.1.10 --port 8080 --image photo.jpg --language rus --mode both# Установка зависимостей
npm install ws axios form-data
# Проверка статуса
node test_client.js --host 192.168.1.10 --port 8080 --mode status
# HTTP API (русский)
node test_client.js --host 192.168.1.10 --port 8080 --image photo.jpg --language rus --mode http
# WebSocket API (русский)
node test_client.js --host 192.168.1.10 --port 8080 --image photo.jpg --language rus --mode ws- Проверьте, что устройство подключено к WiFi
- Убедитесь, что порты 8080 и 8081 не заняты другим приложением
- Проверьте разрешения приложения в настройках Android
- Убедитесь, что устройство и компьютер в одной сети
- Проверьте firewall на устройстве
- Попробуйте использовать IP адрес, отображаемый в приложении
- Убедитесь, что изображение четкое и текст читаемый
- Для русского текста выберите язык "Russian (Русский)" в приложении или укажите
language=rusв запросе - Попробуйте изображение меньшего размера (автоматически изменяется до 2048px)
MIT License - см. файл LICENSE