Розробка outpainting: від полотна до AI-генерації
Ми отримали запит: iOS-додаток для редагування фото — користувачі хочуть розширювати зображення за межі кадру. Вихідне фото 9:16 потрібно перетворити на 16:9 без втрати контенту. Outpainting домальовує бічні області, зберігаючи стиль, освітлення та деталі. Інший кейс — e-commerce: товар на білому фоні, потрібно показати його в інтер'єрі. AI створює оточення без повторної зйомки. Третій приклад — користувач робить скріншот і хоче розширити його до повноцінної сцени. Ми — команда з 5+ роками досвіду в мобільній розробці та інтеграції AI, реалізували більше 10 проєктів з outpainting: від фоторедакторів до візуальних пошуковиків. Нижче — технічні деталі, типові помилки та робочі рішення.
Які проблеми вирішує аутпейнтинг мобільний додаток?
Нестандартні співвідношення сторін — Instagram вимагає 1:1, а вихідник 4:3. Обрізка втрачає контекст. Outpainting розширює фон, зберігаючи композицію. Відсунути камеру — фотограф зняв крупний план, але потрібен загальний вигляд. Одна операція — і AI домальовує оточення. Креативні макети — дизайнеру потрібно об'єднати кілька розширених зображень в єдине полотно. Outpainting робить шви непомітними. Також це генеративне заповнення зображень — потужний інструмент для контент-менеджерів.
Як підготувати маску для outpainting?
Суть outpainting: поміщаємо оригінальне зображення на полотно більшого розміру (з нейтральними полями), передаємо в API як image + mask (маска = нові пусті області), отримуємо заповнений результат.
func prepareOutpaintingCanvas(
original: UIImage,
targetSize: CGSize,
placement: CGPoint // де розмістити оригінал на полотні
) -> (image: UIImage, mask: UIImage) {
// Створюємо полотно потрібного розміру
UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
let context = UIGraphicsGetCurrentContext()!
// Заливаємо сірим (нейтральний колір для областей розширення)
context.setFillColor(UIColor.gray.cgColor)
context.fill(CGRect(origin: .zero, size: targetSize))
// Вставляємо оригінал
original.draw(at: placement)
let compositeImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
// Створюємо маску: чорні пікселі = зберегти, білі = домалювати
// Для DALL-E: альфа-канал замість ч/б
UIGraphicsBeginImageContextWithOptions(targetSize, false, 1.0)
let maskContext = UIGraphicsGetCurrentContext()!
// Білі (прозорі для DALL-E) — нові області
maskContext.setFillColor(UIColor.white.cgColor)
maskContext.fill(CGRect(origin: .zero, size: targetSize))
// Чорні (непрозорі) — оригінальне зображення
maskContext.setFillColor(UIColor.black.cgColor)
maskContext.fill(CGRect(origin: placement, size: original.size))
let maskImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return (compositeImage, maskImage)
}
Позиція оригіналу на полотні визначає напрямок розширення: центр — з усіх боків, лівий край — лише вправо, довільно — користувач керує через drag.
UI управління розширенням (інтерактивне полотно outpainting)
Паттерн взаємодії:
- Користувач бачить вихідне зображення в рамці полотна.
- Може перетягувати зображення всередині рамки (або рухати рамку).
- Обирає підсумковий aspect ratio: 16:9, 4:3, 1:1, або довільний.
- Натискає Розширити.
// Android: draggable image inside canvas with GestureDetector
class OutpaintingView(context: Context) : View(context) {
var imageOffsetX = 0f
var imageOffsetY = 0f
private val gestureDetector = GestureDetector(context, object : SimpleOnGestureListener() {
override fun onScroll(e1: MotionEvent?, e2: MotionEvent, dx: Float, dy: Float): Boolean {
imageOffsetX -= dx
imageOffsetY -= dy
// Обмежуємо зміщення межами полотна
imageOffsetX = imageOffsetX.coerceIn(-maxOffsetX, 0f)
imageOffsetY = imageOffsetY.coerceIn(-maxOffsetY, 0f)
invalidate()
return true
}
})
override fun onDraw(canvas: Canvas) {
canvas.drawColor(Color.DKGRAY) // фон області розширення
canvas.drawBitmap(originalBitmap, imageOffsetX, imageOffsetY, null)
}
}
Відправка на DALL-E 2
// DALL-E 2: image і mask передаються як PNG з альфа-каналом
// В масці: прозорість = редагувати, непрозорість = зберегти
func outpaint(composite: UIImage, mask: UIImage, prompt: String, targetSize: String = "1024x1024") async throws -> UIImage {
// Конвертуємо маску: білі пікселі → прозорі (альфа = 0)
let alphaMask = convertToAlphaMask(mask)
guard let compositeData = composite.pngData(),
let maskData = alphaMask.pngData() else { throw OutpaintError.conversionFailed }
// Запит ідентичний inpainting — той самий ендпоінт /v1/images/edits
return try await sendInpaintRequest(imageData: compositeData, maskData: maskData, prompt: prompt, size: targetSize)
}
private func convertToAlphaMask(_ mask: UIImage) -> UIImage {
UIGraphicsBeginImageContextWithOptions(mask.size, false, 1.0)
guard let context = UIGraphicsGetCurrentContext() else { return mask }
// Інвертуємо: біле → прозоре
context.setBlendMode(.normal)
mask.draw(in: CGRect(origin: .zero, size: mask.size))
// Інверсія альфа-каналу через CIImage
UIGraphicsEndImageContext()
// Використовуємо Core Image для інверсії маски
let ciImage = CIImage(image: mask)!
let inverted = ciImage.applyingFilter("CIColorInvert")
return UIImage(ciImage: inverted)
}
Який AI-движок обрати для outpainting?
Якщо потрібна інтеграція з простим API без налаштування — DALL-E 2 дає відмінну якість з коробки. Якщо потрібна кастомізація (стиль, контроль семпла, довільні розміри) — Stable Diffusion кращий. Ми підбираємо движок під задачу клієнта та допомагаємо з деплоєм моделі на власні сервери. OpenAI DALL-E API — це офіційне джерело для API-специфікацій.
Порівняння DALL-E 2 та Stable Diffusion для outpainting
| Параметр | DALL-E 2 | Stable Diffusion (via Replicate/FAL) |
|---|---|---|
| Формат запиту | image + mask (PNG з альфа) | image + mask (PNG/JPEG) |
| Розміри | 256x256, 512x512, 1024x1024 | Будь-які кратні 64 |
| Підтримка outpainting | Так (як inpainting) | Так (через розширення полотна) |
| Якість | Висока, але мало контролю | Залежить від моделі та LoRA |
| Швидкість | ~10 сек | ~15-30 сек (залежно від розміру) |
| Вартість API | від $0.02 за 1024x1024 | від $0.01 до $0.05 за зображення |
| Гнучкість | Низька (фіксовані розміри) | Висока (довільні розміри, LoRA) |
Stable Diffusion має у 2 рази більшу гнучкість за DALL-E 2 завдяки відкритому коду та можливості тонкого налаштування.
Процес роботи: від ідеї до релізу (outpainting під ключ)
- Аналітика – вивчаємо поточний UX, визначаємо цільові ratio та сценарії використання.
- Проектування – wireframe інтерактивного полотна, API-контракти.
- Реалізація – клієнтська логіка на Swift/Kotlin, бекенд-інтеграція (мобільна розробка нейромережі).
- Тестування – коректність маски, граничні випадки (дуже маленькі/великі зображення).
- Деплой – публікація в App Store/Google Play, моніторинг.
Що входить в роботу
| Етап | Результат |
|---|---|
| Консультація | Оцінка проекту, вибір AI-движка, терміни |
| Розробка | Готовий модуль outpainting з документацією |
| Інтеграція | Вбудовування в існуючий додаток |
| Тестування | QA за чек-листом (шви, стиль, продуктивність) |
| Навчання | Документація та воркшоп для ваших розробників |
| Підтримка | 3 місяці безкоштовної підтримки після релізу (гарантія якості) |
Типові проблеми та їх вирішення
Видимий шов на межі оригіналу та домалюваної частини — трапляється, коли оригінал поміщений з різким краєм на нейтральний фон. Рішення: невеликий градієнтний перехід (feather) на краях маски — розмиваємо маску на 10–20 пікселів.
Невідповідність стилю — модель домалювала щось зовсім іншого стилю. Промпт має описувати всю сцену, а не лише нову частину: «сонячний міський пейзаж, фотореалізм, теплі тони», а не «продовжи».
Терміни та вартість
Базовий outpainting з DALL-E 2 (фіксовані напрямки розширення) — від 5 до 7 днів, вартість від $3000. Інтерактивне draggable полотно з довільним позиціонуванням, множинними ітераціями, історією — від 3 до 4 тижнів, від $8000.
Детальні технічні вимоги
Для інтеграції Stable Diffusion потрібен сервер з GPU (NVIDIA T4 або краще). Ми надаємо готові Docker-образи та інструкції з розгортання. Для DALL-E 2 достатньо API-ключа.Якщо ваш проект потребує outpainting, замовте консультацію — ми підберемо оптимальне рішення. Отримайте консультацію щодо впровадження outpainting у ваш мобільний додаток — зв'яжіться з нами, ми підготуємо детальну комерційну пропозицію.







