Реализация AI-генерации изображений (Kandinsky) в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация AI-генерации изображений (Kandinsky) в мобильном приложении
Простая
~2-3 рабочих дня
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1054
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    874
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация AI-генерации изображений (Kandinsky) в мобильном приложении

Kandinsky — российская модель от Sber AI (КАНДИНСКИЙ 3.1 на момент написания). Основное практическое преимущество для продуктов, работающих с русскоязычной аудиторией: нативное понимание русских промптов без перевода. «Закат над берёзовым лесом» на Kandinsky работает так же, как на западных моделях работает то же на английском — без потерь при трансляции.

Доступные способы интеграции

Fusionbrain API (api.fusionbrain.ai) — официальный API от команды разработчиков Kandinsky. Бесплатный уровень, REST, относительно стабильный. Именно с ним работают большинство интеграций.

Replicate — Kandinsky 2.2 и 3 доступны как community models. Стабильный API, но может быть устаревшая версия модели.

HuggingFace Inference APIkandinsky-community/kandinsky-3. Для прототипов достаточно.

Для продакшена — Fusionbrain API с собственным бэкендом-прокси.

Fusionbrain API: особенности протокола

API использует двухэтапную модель: сначала создаёшь task, затем опрашиваешь статус.

class KandinskyService(private val apiKey: String, private val secretKey: String) {

    // Шаг 1: получить ID модели
    suspend fun getModelId(): String {
        val response = httpClient.get("https://api-key.fusionbrain.ai/key/api/v1/models") {
            header("X-Key", "Key $apiKey")
            header("X-Secret", "Secret $secretKey")
        }
        val models = response.body<List<FusionBrainModel>>()
        return models.first { it.name == "Kandinsky" }.id.toString()
    }

    // Шаг 2: создать задачу генерации
    suspend fun createTask(modelId: String, prompt: String, width: Int = 1024, height: Int = 1024): String {
        val params = JSONObject().apply {
            put("type", "GENERATE")
            put("numImages", 1)
            put("width", width)
            put("height", height)
            put("generateParams", JSONObject().apply {
                put("query", prompt)
            })
        }

        // Multipart запрос
        val requestBody = MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("model_id", modelId)
            .addFormDataPart(
                "params",
                "params.json",
                params.toString().toRequestBody("application/json".toMediaType())
            )
            .build()

        val response = OkHttpClient().newCall(
            Request.Builder()
                .url("https://api-key.fusionbrain.ai/key/api/v1/text2image/run")
                .header("X-Key", "Key $apiKey")
                .header("X-Secret", "Secret $secretKey")
                .post(requestBody)
                .build()
        ).execute()

        return JSONObject(response.body!!.string()).getString("uuid")
    }

    // Шаг 3: polling
    suspend fun pollResult(taskUuid: String): Bitmap? {
        repeat(30) {
            delay(3000)
            val response = OkHttpClient().newCall(
                Request.Builder()
                    .url("https://api-key.fusionbrain.ai/key/api/v1/text2image/status/$taskUuid")
                    .header("X-Key", "Key $apiKey")
                    .header("X-Secret", "Secret $secretKey")
                    .get()
                    .build()
            ).execute()

            val json = JSONObject(response.body!!.string())
            if (json.getString("status") == "DONE") {
                val images = json.getJSONArray("images")
                val base64 = images.getString(0)
                val bytes = Base64.decode(base64, Base64.DEFAULT)
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
            }
        }
        return null
    }
}

Ответ приходит как base64-строка в поле images — не URL. Декодируешь в Bitmap / UIImage непосредственно на клиенте. Сохраняешь во внутреннее хранилище, если нужна история.

Параметры генерации

Kandinsky поддерживает:

  • width / height: от 256 до 1024, кратно 64. Оптимально: 768x768 или 1024x1024
  • style: DEFAULT, ANIME, PORTRAIT, NATURE, REALISTIC (доступность зависит от версии модели)
  • negativePromptDecoder: негативный промпт — список того, чего не должно быть
val params = JSONObject().apply {
    put("type", "GENERATE")
    put("numImages", 1)
    put("width", 768)
    put("height", 1024)
    put("style", "PORTRAIT")
    put("generateParams", JSONObject().apply {
        put("query", "портрет молодой женщины в русском традиционном костюме, детализированный, реализм")
    })
    put("negativePromptDecoder", "размытость, артефакты, деформация, текст, водяной знак")
}

Русский промпт vs английский

Kandinsky понимает русский без деградации качества. Но на практике для технических описаний (архитектура, механизмы) английский промпт даёт более точный результат — модель обучена на смешанном корпусе, и технические термины лучше представлены в английском. Для художественных, пейзажных, портретных сценариев — русский работает отлично.

Для максимального качества — промпт на обоих языках (если UI позволяет), Kandinsky обработает оба.

Интеграция через Replicate (альтернатива)

let replicateBody: [String: Any] = [
    "version": "ai-forever/kandinsky-3:...",
    "input": [
        "prompt": prompt,
        "negative_prompt": negativePrompt,
        "num_steps": 50,
        "guidance_scale": 4.0,
        "scheduler": "DDPMScheduler",
        "width": 1024,
        "height": 1024
    ]
]

Replicate даёт более предсказуемое время ответа (8–20 сек), чем Fusionbrain в пиковые часы.

Типичные ошибки

FAIL статус без объяснений от Fusionbrain — обычно промпт нарушает content policy или слишком короткий (менее 3 слов). Минимальный промпт для стабильной работы — 5–10 слов описания.

Декодирование base64 на main thread — это блокировка UI. Всегда в фоновый поток: DispatchQueue.global().async (iOS) или Dispatchers.Default (Android).

Сроки

Базовая интеграция Fusionbrain API с UI — 3–4 дня. Стили, история генераций, сохранение в галерею, обработка ошибок content policy — 8–12 дней.