80 lines
3.3 KiB
Markdown
80 lines
3.3 KiB
Markdown
```kotlin
|
|
// 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` выполнить:
|
|
```kotlin
|
|
val cropBitmap = Bitmap.createBitmap(
|
|
originalBitmap,
|
|
rect.left,
|
|
rect.top,
|
|
rect.width(),
|
|
rect.height()
|
|
)
|
|
|
|
```
|
|
|
|
|
|
* Конвертировать каждый `cropBitmap` в строку Base64 (JPEG, quality 90).
|
|
|
|
#### 5. Отправка на бэкенд
|
|
|
|
* Сформировать DTO:
|
|
```kotlin
|
|
@Serializable
|
|
data class RecipePayload(
|
|
val clientVersion: String = "1.0",
|
|
val snippets: List<String> // Array of Base64 strings
|
|
)
|
|
|
|
```
|
|
|
|
|
|
* Отправить `POST`-запрос через Ktor на эндпоинт `/api/v1/recognize`. |