Розробка мобільного додатку для фотопечаті
Додаток для фотопечаті—один з небагатьох мобільних продуктів, де фізичне й цифрове перетинаються безпосередньо: користувач вибирає фото на смартфоні, а через 2–5 днів тримає в руках готовий відпечаток. Технічно це означає роботу з повнорозмірними файлами (HEIC, RAW-конвертація, колірпроба), складний UI редактора та інтеграцію з типографським API.
Робота з зображеннями: HEIC та колірпроба
iPhone за замовчуванням знімає в HEIC (High Efficiency Image Container). Більшість типографій приймають лише JPEG. Конвертація—на пристрої або на серверу:
import Photos
import ImageIO
func convertHEICtoJPEG(asset: PHAsset, completion: @escaping (Data?) -> Void) {
let options = PHImageRequestOptions()
options.deliveryMode = .highQualityFormat
options.isNetworkAccessAllowed = true
options.isSynchronous = false
PHImageManager.default().requestImage(
for: asset,
targetSize: PHImageManagerMaximumSize,
contentMode: .aspectFit,
options: options
) { image, info in
guard let cgImage = image?.cgImage else {
completion(nil)
return
}
let mutableData = NSMutableData()
guard let destination = CGImageDestinationCreateWithData(
mutableData, kUTTypeJPEG as CFString, 1, nil
) else {
completion(nil)
return
}
let jpegOptions: [CFString: Any] = [
kCGImageDestinationLossyCompressionQuality: 0.95,
// Зберігаємо sRGB для передбачуваної колірпроби в типографії
kCGImagePropertyColorModel: kCGImagePropertyColorModelRGB
]
CGImageDestinationAddImage(destination, cgImage, jpegOptions as CFDictionary)
CGImageDestinationFinalize(destination)
completion(mutableData as Data)
}
}
Мінімальне розрішення для якісної печаті 10×15 см—1200×900 px при 300 DPI. Додаток повинен попереджувати, якщо фото занадто маленьке:
func checkPrintQuality(image: UIImage, printSizeInches: CGSize) -> PrintQuality {
let requiredWidth = printSizeInches.width * 300
let requiredHeight = printSizeInches.height * 300
return image.size.width >= requiredWidth && image.size.height >= requiredHeight
? .good
: image.size.width >= requiredWidth * 0.7 ? .acceptable : .poor
}
Редактор: кадрування та коррекція
Редактор—центральний екран додатку. Для базових операцій (crop, rotate, brightness, contrast) на iOS використовуємо Core Image + CIFilter:
func applyBrightnessContrast(
to image: CIImage,
brightness: Float,
contrast: Float
) -> CIImage {
guard let filter = CIFilter(name: "CIColorControls") else { return image }
filter.setValue(image, forKey: kCIInputImageKey)
filter.setValue(brightness, forKey: kCIInputBrightnessKey)
filter.setValue(contrast, forKey: kCIInputContrastKey)
return filter.outputImage ?? image
}
На Android—Coil + android.graphics.ColorMatrix для базових фільтрів, для складних—GPUImage library.
Кадрування під формати печаті (10×15, 15×20, 20×30, квадрат)—обов'язково підтримувати фіксований aspect ratio з плавною анімацією crop-прямокутника.
Завантаження файлів у типографію
Фотографії важать 3–8 МБ кожна. При замовленні 30+ знімків—це 100–250 МБ. Завантаження пакетами з можливістю паузи/возобновлення:
// Android: WorkManager для надійного фонового завантаження
class PhotoUploadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val photoIds = inputData.getStringArray("photoIds") ?: return Result.failure()
val orderId = inputData.getString("orderId") ?: return Result.failure()
photoIds.forEachIndexed { index, photoId ->
val photo = photoRepository.getById(photoId)
val success = uploadPhoto(photo, orderId)
if (!success) return Result.retry()
setProgress(workDataOf(
"uploaded" to index + 1,
"total" to photoIds.size
))
}
return Result.success()
}
}
// Запуск з Constraints—лише по Wi-Fi для великих замовлень
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.build()
Інтеграція з типографією
API типографій—як правило, REST з multipart/form-data для завантаження файлів та окремими ендпоінтами для створення замовлення. Розповсюджені поставщики: Cewe API, Fujifilm API, приватні типографії з кастомним REST.
Після завантаження всіх файлів та створення замовлення—додаток показує статус: «У обробці» → «Передано в печать» → «Відправлено» (з трек-номером).
Ориентири по терміне
Базова версія (вибір фото, кадрування, завантаження, оплата, історія замовлень): 5–8 тижнів. Розширений редактор (фільтри, текст, колажи)—ще 3–4 тижні. Вартість розраховується індивідуально.







