ionic-team / ionic-team/capacitor-camera

Gallery image decoding lacks BitmapFactory.Options/inSampleSize downsampling (potential OOM on large images)

Open
#76 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
4
Forks
1
Avg merge
2d 1h
Merged PRs (30d)
2

Description

### Description

`IonCameraFlow.handleGalleryMediaResults()` (android/src/main/java/com/capacitorjs/plugins/camera/IonCameraFlow.kt)
decodes gallery-selected images at full resolution before reading EXIF metadata:

```kotlin
val bitmap = BitmapFactory.decodeFile(mediaResult.uri)
```

This call passes no `BitmapFactory.Options`, so there's no `inSampleSize` downsampling — a full-resolution `Bitmap` is allocated in memory purely to extract EXIF data, even though only image dimensions/orientation are needed. On devices with limited memory, or with very large source images (e.g. modern phone cameras producing 12+ MP photos, or large PNG screenshots), this can cause high memory pressure or an `OutOfMemoryError`.

A related helper, `IONCAMRMediaHelper.getImageResolution()` (from `io.ionic.libs.ioncameralib`), appears to follow the same pattern based on its usage — reading image dimensions without the standard two-pass `inJustDecodeBounds` → calculate `inSampleSize` → decode approach recommended by the [Android docs on loading large bitmaps efficiently](https://developer.android.com/topic/performance/graphics/load-bitmap).

### Observed mitigation, but not a fix

`CameraPlugin.java` does catch `OutOfMemoryError` around related bitmap processing, so the plugin doesn't crash uncontrolled today — but that's a reactive safety net, not a fix for the underlying unbounded allocation.

### Suggested fix

Since only image dimensions/orientation are needed here (not the full pixel buffer), the simplest fix may be to skip `decodeFile` entirely for this purpose — Android's `ExifInterface` class can read orientation directly from the file without decoding a bitmap at all. If a bitmap decode is genuinely needed elsewhere in the flow, use the standard two-pass approach: decode with `inJustDecodeBounds = true` first to read dimensions cheaply, then calculate `inSampleSize` before a real decode.

### Environment

- `@capacitor/camera` version: `8.2.3` (latest stable at time of filing)
- Checked `CHANGELOG.md` — no entries reference bitmap decoding, downsampling, `inSampleSize`, or OOM handling in this area.

Contributor guide

Open the contributing guide

Research direction

Start in android/src/main/java/com/capacitorjs/plugins/camera/IonCameraFlow.kt at IonCameraFlow.handleGalleryMediaResults() and inspect how the decoded bitmap is used for EXIF metadata. Check the related IONCAMRMediaHelper.getImageResolution() usage and CameraPlugin.java's bitmap error handling. Done means gallery images no longer require an unbounded full-resolution allocation for dimensions or orientation, with focused Android tests or verification covering large images.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, java, kotlin
Domain
mobile
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.