Image Post Publishing: Compression, Upload, UI
Have you ever had an app crash when selecting a photo from the gallery? Or image uploads taking forever, only for the post to appear without pictures? We are a mobile development team with over 5 years of experience — we implement post publishing with images so that the user doesn’t wait and the developer doesn’t chase bugs. This article covers the key stages: photo selection, cropping, compression, upload, and display. We’ll explain how to avoid common pitfalls and build a turnkey solution in 2–5 days.
How to Organize Image Selection and Cropping
Photo selection is the first step where many projects stumble. On iOS we use PHPickerViewController (iOS 14+). Set selectionLimit — usually 1–10 for a post. PHPickerFilter.images excludes videos. On Android we use the standard ActivityResultContracts.PickMultipleVisualMedia or a custom picker. However, permissions are crucial: on iOS you need NSPhotoLibraryUsageDescription and must handle ATT (AppTrackingTransparency) for iOS 14.5+. On Android READ_EXTERNAL_STORAGE or READ_MEDIA_IMAGES (API 33+) is enough.
Cropping is often required for a uniform post appearance. On iOS we use TOCropViewController — an open-source library proven in hundreds of projects. It supports aspect ratio, rotation, and a custom toolbar. If an in-house solution is needed, a custom UIScrollView with UIImageView works, where we convert crop area coordinates into image coordinates via CGAffineTransform. On Android we use uCrop — a flexible and stable tool. For complex cases (like cropping with a 45° rotation), uCrop provides built-in support.
Compression Before Upload: Why It’s Critical
Compression directly affects speed and data usage. We use a unified standard: maximum side 1440px (since posts need larger images than chats), JPEG quality 80%. The resulting file is 200–400 KB with excellent visual quality. On iOS the work is done in DispatchQueue.global(qos: .userInitiated) using UIGraphicsImageRenderer and jpegData(compressionQuality: 0.80). For multi-selection (5+ photos), we process sequentially in the background and show progress. On Android we use Bitmap.createScaledBitmap() with filtering true and compress(JPEG, 80, stream). We pre-calculate inSampleSize via BitmapFactory.Options to avoid loading the original into memory, preventing OutOfMemoryError on devices with 2 GB RAM.
Upload and Optimistic Post
We upload images before creating the post. The algorithm:
- Upload all photos in parallel — each as a separate
URLSessionUploadTask(iOS) orlaunchin coroutines (Android). - Collect the array of URLs/keys from responses.
- Create the post with that array via API.
Progress is displayed cumulatively: "uploaded X of N photos". If one photo out of five fails, we retry only that one — the rest are already on the server.
Optimistic post: We create a local database record (Core Data, Room) immediately with status uploading and display it in the feed with a loading indicator. On success the status changes to published, on failure to failed with a retry button. The user doesn’t wait.
Why Parallel Upload Is Faster
Comparison of sequential vs. parallel upload for 5 photos:
| Parameter | Sequential Upload | Parallel Upload |
|---|---|---|
| Time for 5 photos | ~10 sec (2 sec each) | ~2 sec (minimum) |
| Error handling complexity | Easier | Harder, but we solved it |
| UX | Blocks UI | Progress shown |
With parallel upload, it’s also important to control the number of concurrent tasks. On iOS we use URLSession with HTTPMaximumConnectionsPerHost (default 6), on Android we use Dispatchers.IO with a semaphore.
Display in Feed: Algorithms and Patterns
The photo grid is UICollectionView with flow layout (iOS) or LazyVerticalGrid (Compose). The first photo is large, the rest form a 2×N grid (Instagram pattern). Lazy loading via Kingfisher (iOS) or Coil (Android) with disk caching. Placeholders use blur-hash from metadata or solid color from dominant color. For images with transparency (PNG) we use SDWebImage (iOS) or Glide (Android), since Kingfisher/Coil are optimized for JPEG.
What’s Included in Our Work
We deliver a turnkey module:
- Integration of gallery photo selection (including ATT permissions on iOS).
- Cropping with specified aspect ratios (1:1, 4:5, 16:9).
- Compression with configurable parameters (maximum side, quality, format).
- Parallel server upload with progress.
- Optimistic local database save.
- Feed display with lazy loading.
- API documentation and help with App Store moderation.
- Quality guarantee and post-deployment support.
Timelines and Pricing
Basic integration takes 1–3 days. Adding cropping, multi-selection, and optimistic UI adds another 1–2 days. Pricing is calculated individually — contact us for a project estimate. Our team has 5+ years of experience and 20+ successful projects with media content. We guarantee stable operation and compliance with App Store and Google Play guidelines. Get a consultation for your project — get in touch.







