Image Saving
Camera Roll
Smartphone Tips
Photo Management
Save Photos

How can I save an image to the camera roll?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In app development, save to camera roll usually means writing an image into the user's photo library so it appears in the Photos app on iOS or the gallery on Android. The exact API depends on the platform, but the overall flow is the same: obtain the image data, request the correct permission, and write the file through the platform's media APIs.

Saving an image on iOS

On iOS, the modern API surface is the Photos framework. Your app needs a usage description in Info.plist, and then it can request authorization and create an asset in the photo library.

swift
1import Photos
2import UIKit
3
4func saveImageToLibrary(_ image: UIImage) {
5    PHPhotoLibrary.requestAuthorization(for: .addOnly) { status in
6        guard status == .authorized || status == .limited else {
7            print("Photo library access denied")
8            return
9        }
10
11        PHPhotoLibrary.shared().performChanges {
12            PHAssetChangeRequest.creationRequestForAsset(from: image)
13        } completionHandler: { success, error in
14            if success {
15                print("Image saved")
16            } else {
17                print(error?.localizedDescription ?? "Save failed")
18            }
19        }
20    }
21}

Your Info.plist must include NSPhotoLibraryAddUsageDescription with a clear explanation of why the app wants to save images.

If you already have raw image data rather than a UIImage, decode it first and then create the asset.

Saving an image on Android

On Android, the recommended approach is to insert the image through MediaStore. This makes the file visible to gallery apps and works correctly with scoped storage.

kotlin
1import android.content.ContentValues
2import android.content.Context
3import android.graphics.Bitmap
4import android.os.Build
5import android.provider.MediaStore
6
7fun saveBitmapToGallery(context: Context, bitmap: Bitmap, fileName: String) {
8    val resolver = context.contentResolver
9    val collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
10
11    val values = ContentValues().apply {
12        put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
13        put(MediaStore.Images.Media.MIME_TYPE, "image/png")
14        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
15            put(MediaStore.Images.Media.IS_PENDING, 1)
16        }
17    }
18
19    val uri = resolver.insert(collection, values) ?: error("Failed to create media entry")
20
21    resolver.openOutputStream(uri).use { stream ->
22        checkNotNull(stream) { "Failed to open output stream" }
23        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
24    }
25
26    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
27        values.clear()
28        values.put(MediaStore.Images.Media.IS_PENDING, 0)
29        resolver.update(uri, values, null, null)
30    }
31}

This writes the bitmap through the system media provider instead of writing directly into a random filesystem path.

Saving an image downloaded from the network

In many apps, the image comes from a URL rather than from the camera. The right pattern is to download the bytes, decode them into an image object, and then pass that image to the platform-specific save function.

On iOS, that means turning the downloaded data into UIImage. On Android, it often means decoding the bytes into a Bitmap. The final save step should still go through Photos or MediaStore rather than bypassing the media library.

Permissions and user expectations

Saving into the user's photo library is a privacy-sensitive action. A good app should not save silently unless that behavior is obvious and requested by the user.

You should also distinguish between read access and add-only access. Some platforms let you request narrower permission scopes, which is better for privacy and often easier to justify during review.

Common Pitfalls

The most common problem on iOS is forgetting the Info.plist usage description. Without it, the save attempt can fail or the app can be rejected.

On Android, a frequent mistake is writing a file directly to external storage and expecting it to appear immediately in gallery apps. Using MediaStore is the more reliable approach for modern Android versions.

Another issue is doing image decoding and compression on the main thread. Large images can cause visible UI stalls if you perform the work synchronously.

Summary

  • Saving to the camera roll means writing into the platform photo library, not just creating a local file.
  • On iOS, use the Photos framework and include NSPhotoLibraryAddUsageDescription.
  • On Android, use MediaStore so the saved image is managed correctly by the system gallery.
  • Decode downloaded image data before saving it through the media APIs.
  • Handle permissions carefully and avoid blocking the main thread with heavy image work.

Course illustration
Course illustration

All Rights Reserved.