Files

3.3 KiB

// filename: AndroidCropPipelinePlan.md
// Architectural plan for building an Android handwriting text block cropper MVP using ML Kit.

Архитектура приложения

Приложение нацелено на максимальную скорость и простоту: оно получает кадр с камеры, определяет границы бланка рецепта, выравнивает его, находит области с рукописным текстом и отправляет нарезку на бланке в виде массива Base64 на бэкенд.


Библиотеки и стек (Android / Kotlin)

  • UI Framework: Jetpack Compose + Material 3.
  • Camera: androidx.camera:camera-camera2 (CameraX).
  • Document Scanner (Выравнивание бланка): com.google.android.gms:play-services-mlkit-document-scanner (Google ML Kit Document Scanner API).
  • Text Detection (Поиск BoundingBoxes): com.google.android.gms:play-services-mlkit-text-recognition (ML Kit Text Recognition).
  • Network / HTTP: io.ktor:ktor-client-android + io.ktor:ktor-client-content-negotiation (Ktor Client).
  • Image Processing: io.coil-kt:coil-compose (отображение) + стандартный android.graphics.Bitmap.

Пошаговый план разработки для Агента

1. Инициализация и разрешения

  • Настроить build.gradle.kts с указанными выше библиотеками.
  • Запросить стандартные разрешения CAMERA и доступ к хранилищу.

2. Захват и выравнивание бланка (Document Scanner)

  • Использовать GmsDocumentScannerOptions:

  • Режим: SCANNER_MODE_FULL.

  • Формат: RESULT_FORMAT_JPEG.

  • Лимит страниц: 1.

  • Запустить интентом GmsDocumentScanning.getClient(options).getStartScanIntent(...).

  • Получить обратно отсканированный, обрезанный и выровненный Uri рецепта.

3. Поиск рукописных прямоугольников (Bounding Boxes)

  • Преобразовать Uri выровненного бланка в InputImage.fromFilePath.
  • Запустить TextRecognition.getClient(TextRecognizerOptions.DEFAULT_OPTIONS).
  • Из полученного Text пройтись по Text.TextBlock или Text.Line.
  • Извлечь прямоугольники: val rect: Rect? = block.boundingBox.

4. Нарезка Bitmap (Cropping)

  • Загрузить исходный Bitmap бланка.
  • Для каждого полученного Rect выполнить:
val cropBitmap = Bitmap.createBitmap(
    originalBitmap, 
    rect.left, 
    rect.top, 
    rect.width(), 
    rect.height()
)

  • Конвертировать каждый cropBitmap в строку Base64 (JPEG, quality 90).

5. Отправка на бэкенд

  • Сформировать DTO:
@Serializable
data class RecipePayload(
    val clientVersion: String = "1.0",
    val snippets: List<String> // Array of Base64 strings
)

  • Отправить POST-запрос через Ktor на эндпоинт /api/v1/recognize.