AI-инпейнтинг в мобильном приложении: от маски до результата

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
AI-инпейнтинг в мобильном приложении: от маски до результата
Сложный
~5 дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    746
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1162
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    969
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    563

AI-инпейнтинг в мобильном приложении: от маски до результата

Вы сделали отличное фото на iPhone, но в кадр попал случайный прохожий. В приложении нужно стереть его за пару касаний — это задача для AI-инпейнтинга. Технически решение состоит из трёх этапов: создать маску, отправить изображение на API модели, применить результат. Каждый этап требует точного подхода, иначе получите артефакты или долгую загрузку. Разберём, как реализовать это на практическом уровне с кодом и конфигами.

Инпейнтинг — это технология замены области изображения на основе контекста. В мобильных приложениях мы используем облачные API (DALL·E 2, Stable Diffusion) для генерации контента. Но ключевая сложность — рисование маски на устройстве. От качества маски зависит 80% результата. Если маска неточная, модель заменит лишнее или оставит следы объекта. Поэтому первой задачей стоит реализация интуитивного инструмента рисования.

Почему качество маски определяет результат inpainting?

Маска — бинарное изображение, где белые пиксели обозначают область редактирования. Модель использует её как подсказку. Если маска выходит за границы объекта, модель «дорисует» соседние элементы, что приведёт к неестественному переходу. Если маска слишком узкая, останутся части удаляемого объекта. Поэтому важно реализовать точное рисование с возможностью масштабирования и отмены действий.

Как реализовать рисование маски на iOS?

Для iOS используем CAShapeLayer и UIBezierPath. При касании рисуем круги по траектории движения, объединяя их в один path. Маска получается как чёрно-белое изображение: чёрный фон — неизменяемая область, белые мазки — область интереса.

class MaskDrawingView: UIView {
    private var maskLayer = CAShapeLayer()
    private var path = UIBezierPath()
    private var brushSize: CGFloat = 30

    override func draw(_ rect: CGRect) {
        UIColor.black.setFill()
        UIRectFill(rect)
        UIColor.white.setFill()
        path.fill()
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let point = touch.location(in: self)
        let circle = UIBezierPath(arcCenter: point, radius: brushSize / 2, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        path.append(circle)
        setNeedsDisplay()
    }

    func getMaskImage() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0)
        layer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}

Для плавности используем UIGraphicsImageRenderer и оптимизируем рендеринг через displayLayer. На iPad с Apple Pencil маска получается точнее — можно увеличить разрешение path.

Как реализовать рисование маски на Android?

На Android используем кастомный View с Canvas и Paint. Рисуем круги на отдельном битмапе, который затем передаётся как маска. Важно настроить сглаживание и размер кисти под плотность экрана.

class MaskDrawingView(context: Context) : View(context) {
    private val maskBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    private val canvas = Canvas(maskBitmap)
    private val paint = Paint().apply {
        color = Color.WHITE
        style = Paint.Style.FILL
        strokeWidth = brushSize
        isAntiAlias = true
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_MOVE -> {
                canvas.drawCircle(event.x, event.y, brushSize / 2, paint)
                invalidate()
            }
        }
        return true
    }
}

Для производительности используем Bitmap.Config.HARDWARE на Android 8+ и избегаем лишних копирований.

Как интегрировать DALL·E 2 Inpainting?

DALL·E 2 принимает только PNG с альфа-каналом, где прозрачные пиксели обозначают область редактирования. То есть маска вкладывается в альфа-канал изображения. Максимальный размер запроса — 4 МБ. Отправляем multipart/form-data:

func inpaint(image: UIImage, mask: UIImage, prompt: String) async throws -> UIImage {
    guard let imageData = image.pngData(), let maskData = mask.pngData() else {
        throw InpaintError.invalidImage
    }

    var request = URLRequest(url: URL(string: "https://api.openai.com/v1/images/edits")!)
    request.httpMethod = "POST"
    request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")

    let boundary = UUID().uuidString
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

    var body = Data()
    // image (обязательно PNG, RGBA, макс 4 МБ)
    body.appendMultipart(boundary: boundary, name: "image", filename: "image.png", contentType: "image/png", data: imageData)
    // mask (PNG, RGBA, прозрачность = область изменения)
    body.appendMultipart(boundary: boundary, name: "mask", filename: "mask.png", contentType: "image/png", data: maskData)
    // prompt
    body.appendMultipart(boundary: boundary, name: "prompt", data: prompt.data(using: .utf8)!)
    // size (должен совпадать с размером входного изображения)
    body.appendMultipart(boundary: boundary, name: "size", data: "1024x1024".data(using: .utf8)!)
    body.append("--\(boundary)--\r\n".data(using: .utf8)!)
    request.httpBody = body

    let (data, _) = try await URLSession.shared.data(for: request)
    let response = try JSONDecoder().decode(ImageResponse.self, from: data)
    // Загружаем результат
    let (imageData2, _) = try await URLSession.shared.data(from: URL(string: response.data[0].url)!)
    return UIImage(data: imageData2)!
}

Ограничение DALL·E 2: принимает только PNG с альфа-каналом (RGBA). Маска передаётся через прозрачность: прозрачные пиксели = область редактирования. Не чёрно-белая маска как в SD, а альфа-канал. Максимальный размер — 4 МБ.

Какие альтернативы существуют? Stable Diffusion Inpainting

SD inpainting через Replicate принимает base64 для image и mask. Параметр strength управляет глубиной замены: 1.0 — полная замена, 0.5 — мягкое смешение с оригинальным контентом. Это даёт больше гибкости, чем DALL·E 2.

val body: [String: Any] = [
    "version": "...", // SD inpainting model
    "input": [
        "prompt": prompt,
        "image": "data:image/jpeg;base64,${imageBase64}",
        "mask": "data:image/png;base64,${maskBase64}",
        "num_inference_steps": 25,
        "guidance_scale": 7.5,
        "strength": 0.99 
    ]
]

Сравнение моделей inpainting:

Модель Входной формат Макс. размер Особенности
DALL·E 2 PNG с альфа-каналом 4 МБ Высокое качество, но жёсткие требования по формату
SD через Replicate JPEG/PNG base64 10 МБ Гибкость, настраиваемый strength, ниже стоимость за запрос

Как обрабатывать изображения разного размера?

Перед отправкой в API изображение ресайзится до требуемого размера (например, 1024×1024 для DALL·E 2). Используем aspect fill, чтобы сохранить пропорции и обрезать лишнее. После генерации результат накладывается на оригинал в координатах маски. Для этого сохраняем исходные размеры и положение превью.

func resizeAndCrop(_ image: UIImage, to size: CGSize) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
    let aspectFill = max(size.width / image.size.width, size.height / image.size.height)
    let newSize = CGSize(width: image.size.width * aspectFill, height: image.size.height * aspectFill)
    let origin = CGPoint(x: (size.width - newSize.width) / 2, y: (size.height - newSize.height) / 2)
    image.draw(in: CGRect(origin: origin, size: newSize))
    let result = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return result
}

Как обеспечить плавный UX при загрузке?

Запрос к API занимает от 1 до 5 секунд в зависимости от модели и размера изображения. Показываем анимацию загрузки с прогрессом (на SD можно отследить через polling). На iOS используем SwiftUI ProgressView, на Android CircularProgressIndicator. После получения результата — плавный переход через cross-fade.

Что входит в нашу работу по интеграции

  1. Анализ ваших требований и выбор оптимального API (DALL·E 2, SD или комбинация).
  2. Разработка UI для рисования маски с поддержкой undo/redo, изменения размера кисти, масштабирования.
  3. Интеграция выбранного API с обработкой ошибок, ретраями и кэшированием.
  4. Преобразование изображений: ресайз, кроп, наложение результата.
  5. Документация и обучение вашей команды.
  6. Пост-релиз техподдержка 3 месяца.

Свяжитесь с нами для технической оценки вашего проекта — мы поможем выбрать подходящий API и реализуем интеграцию в кратчайшие сроки. Работаем с гарантией результата и соблюдением сроков. Получите консультацию — пришлите описание задачи, и мы оценим её в рамках бесплатного аудита.

Сроки реализации

  • Базовая интеграция (один API + экран рисования маски) — от 5 до 8 дней.
  • Полноценный редактор (undo/redo, мульти-API, наложение) — от 3 до 4 недель.

Сроки уточняются после анализа вашего проекта.

AI и ML в мобильных приложениях: CoreML, TFLite и on-device модели

Мы различаем два принципиально разных подхода: приложение с on-device AI и приложение, которое просто вызывает облачное API. Первое работает без интернета, не отправляет данные пользователя на сторонние серверы и отвечает за 50 миллисекунд. Второе зависит от задержки сети и тарифного плана. Выбор архитектуры — ключевой этап, который напрямую влияет на стоимость, приватность и пользовательский опыт. Наш опыт показывает: в 70% проектов on-device инференс оказывается дешевле в долгосрочной перспективе за счёт исключения серверных затрат.

Как выбрать между CoreML и TFLite для on-device инференса?

CoreML — нативный фреймворк Apple для запуска ML-моделей на устройстве. Поддерживает Neural Engine (начиная с A11 Bionic), GPU и CPU как fallback. Модели конвертируются в формат .mlmodel через coremltools из PyTorch, ONNX или TensorFlow. Конвертация — не всегда тривиальна: кастомные слои требуют реализации MLCustomLayer, а квантизация до INT8 иногда заметно роняет точность на специфических данных. Мы гарантируем, что итоговая модель проходит валидацию на реальных данных до и после конвертации.

TensorFlow Lite — кросс-платформенная альтернатива для Android и Flutter. На Android использует NNAPI (Neural Networks API) для хардварного ускорения — с Android 10 NNAPI стабильнее, до этого лучше явно использовать GPU delegate через GpuDelegate. Типичная ошибка: модель обучена на нормализованных данных в диапазоне [0,1], а в приложении на вход подаётся [0,255] — инференс работает, но с бессмысленными результатами без ошибки. Мы включаем модуль автоматической валидации входных данных в SDK.

Для задач классификации изображений, детекции объектов и сегментации доступны готовые оптимизированные модели. YOLOv8 в CoreML формате запускает детекцию кадра 640×640 за 15–20 мс на iPhone 14 Neural Engine. MobileNetV3 на TFLite с GPU delegate — около 8 мс на Pixel 7 при классификации.

Параметр CoreML TFLite
Платформы iOS, macOS, watchOS Android, iOS, Linux, embedded
Хардварное ускорение Neural Engine, GPU, CPU NNAPI, GPU (OpenCL/OpenGL), CPU
Поддержка квантизации FP16, INT8 (с coremltools) FP16, INT8, dynamic range
Кастомные операции Через MLCustomLayer (Swift) Через делегаты (Java/Kotlin)
Размер бандла модели ~3–5 МБ (MobileNetV2 quantized) ~2–4 МБ

Что делать, если нужна генерация текста на устройстве?

Запуск небольших языковых моделей на устройстве стал реальностью в последние несколько лет. Apple Intelligence использует собственные модели через Private Cloud Compute, но для сторонних разработчиков доступны другие пути.

llama.cpp с Metal backend на iOS — работающий подход для phi-3-mini (3.8B параметров, 4-bit квантизация, ~2.3 ГБ). Инференс: 15–25 токенов/секунду на iPhone 15 Pro. Для интеграции в Swift используем Swift Package llama.swift или обёртку через C-интерфейс llama.h. Бинарник к приложению не прикладываем — модель скачивается при первом запуске и хранится в Application Support. Наши сертифицированные разработчики настраивают инкрементальную загрузку, чтобы не блокировать первый запуск.

На Android аналог — Google AI Edge (бывший MediaPipe LLM Inference API) с поддержкой Gemma-2B. Работает через GPU delegate, на Tensor G3 чипе Pixel 8 Pro — около 20 токенов/секунду.

Ограничения реальны: модели больше 4B параметров на мобильных устройствах по-прежнему медленны. Для сложных задач рассуждения on-device LLM уступает GPT-4o в качестве. Гибридный подход — on-device для коротких задач и приватных данных, облако для сложных запросов — часто оптимален. Оценим ваш кейс и предложим баланс производительности и приватности — пишите.

Интеграция OpenAI API и других облачных моделей

Для сценариев, где cloud inference допустим, интеграция OpenAI, Anthropic или Google Gemini — это HTTP клиент + streaming SSE. В Swift удобно через AsyncThrowingStream для стриминговых ответов. В Kotlin — через Flow.

Критически важно: API-ключи никогда не хранятся в бандле приложения. Даже обфусцированный ключ извлекается из IPA за 10 минут через strings или frida. Правильная архитектура: мобильное приложение → собственный backend → OpenAI API. Backend контролирует rate limiting, логирует запросы, защищает ключ.

Что входит в работу (deliverables)

  • Обученная и квантизированная модель под целевое устройство (документация по метрикам)
  • SDK для интеграции (Swift/Kotlin/Flutter) с примерами вызова
  • Тесты производительности на 3–5 реальных устройствах
  • Инструкция по обновлению модели OTA
  • Поддержка при прохождении модерации App Store / Google Play (проверка соответствия Guidelines 4.2, 5.1)
  • 2 недели технической поддержки после релиза

Типичный пайплайн проекта

  1. Анализ задачи — замеряем latency, privacy, size, поддерживаемые устройства.
  2. Прототипирование модели — в Python, оценка accuracy на целевых данных.
  3. Конвертация и квантизация — под CoreML/TFLite с валидацией.
  4. Интеграция в приложение — модель оборачивается в сервисный слой (легко подменять CoreML → TFLite → облако).
  5. Тестирование — на реальных девайсах, замер FPS, RAM, батареи.
  6. Деплой — через TestFlight / Firebase App Distribution, мониторинг метрик.

Сроки: интеграция готовой CoreML/TFLite модели — 1–2 недели, разработка кастомной модели с мобильной оптимизацией — от 6 недель, on-device LLM чат с персонализацией — 4–8 недель.

Почему мы беремся за сложные кейсы?

10+ лет опыта в мобильной разработке, 50+ внедрённых AI/ML решений, гарантия совместимости с актуальными версиями iOS и Android. Все проекты проходят code review и нагрузочное тестирование. В стоимость уже входит подготовка документации для модерации и обучение вашей команды.

Свяжитесь с нами — мы поможем выбрать архитектуру и внедрить ML в ваше приложение под ключ. Закажите аудит существующего решения — бесплатно оценим потенциал экономии серверных затрат (в некоторых проектах экономия достигает $10k в месяц).