chooseFromGallery returns the original library asset (HEIC on iOS) where pickImages re-encoded to JPEG
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 55/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 静か
- 技術スタック
- swift, typescript
- 領域
- mobile-dev
調査の方向性
IONCAMRPhotoLibraryService.fetchImage(from:) とその fetchImageURL(for: asset) パスから始め、次に didFinishPicking と thumbnailAsData の分岐を調べます。iOS の動作を Android の onChooseFromGalleryResult および createImageMediaResult と比較します。選択したギャラリーフォーマットの動作が選択した解像度と一貫しており、chooseFromGallery のドキュメントで結果として得られるエンコーディングが説明されていれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
chooseFromGallery returns the original photo-library asset without re-encoding it, so on iOS a normally-shot iPhone photo comes back as HEIC. The deprecated pickImages/getPhoto it replaces always re-encoded to JPEG, so migrating off them is a behaviour change for any app that assumed a browser-renderable format.
This isn't obvious from the docs: ChooseFromGalleryOptions carries a quality field documented as "Only applicable for MediaType.Photo and JPEG format", which reads as though photos come back as JPEG.
Where it happens
iOS — IONCameraLib's IONCAMRPhotoLibraryService.fetchImage(from:) builds its result from fetchImageURL(for: asset), which is asset.requestContentEditingInput { … editingInput?.fullSizeImageURL }. That URL is the original asset in the library; nothing decodes or re-encodes it.
Worth noting this applies to both selection modes, not just allowMultipleSelection: true. didFinishPicking branches on thumbnailAsData rather than on the selection mode:
if self.thumbnailAsData {
let results = await self.fetchMultipleResult(assetArray) // original asset URL
…
} else {
let item = await self.fetchSingleResult(assetArray.first) // UIImage → toData()
…
}
IONCAMRGalleryOptions decodes thumbnailAsData with a default of true, and ChooseFromGalleryOptions in the plugin's TypeScript has no field that maps to it — so a chooseFromGallery call can only ever take the first branch.
Android — ioncamera-android's onChooseFromGalleryResult resolves the picked URI to a file path and passes it to createImageMediaResult, whose bitmap decode/compress feeds only the base64 thumbnail; the result's uri still names the original file. Less visible in practice because Android cameras usually write JPEG, but the same pass-through.
takePhoto is unaffected — UIImage.toData(with:) honours encodingType, which defaults to JPEG.
Why it matters
HEIC uploads fine and then fails to render for most viewers: Chrome and Firefox decode none of it, and server-side sharp's prebuilt libvips ships no HEVC decoder, so thumbnailing fails too. An app that offers "choose from library" and accepts what it gets will store images that a majority of its users see as broken — and the failure lands after upload, where the only remedy is rejecting a photo the user already chose.
Versions: @capacitor/camera 8.2.2, IONCameraLib 1.0.5, ioncamera-android 1.0.2.
Steps to reproduce
- On an iPhone with Settings → Camera → Formats → High Efficiency, take a photo.
- Call
chooseFromGallery({ mediaType: MediaTypeSelection.Photo, includeMetadata: true })and pick it. results[0].metadata.formatisheic, anduripoints at a.HEICfile.
Expected (and what pickImages did): a JPEG.
Possible resolutions
Any one of these would be enough, in rough order of preference:
- Give
ChooseFromGalleryOptionsanencodingTypelikeTakePhotoOptionshas, and re-encode to it. - Re-encode gallery picks to JPEG by default, matching the deprecated methods' behaviour.
- If pass-through is the intended design, say so in the
chooseFromGallerydocs and in the deprecation notes ongetPhoto/pickImages— the format change is the migration's sharpest edge and currently isn't mentioned.
- 主要言語
- TypeScript
- スター
- 6
- フォーク
- 3
- 平均マージ
- 2日 21時間
- マージ済み PR(30日)
- 4
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
ionic-team/capacitor-camera のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
ionic-team/capacitor-camera#75 · リアクション 1 件 ·
-
[Bug]: Crash SecurityException: No persistable permission grants found in IONCAMROpenPhotoPickerActivity対応中かも @ankit-edii が 22 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
ionic-team/capacitor-camera#58 · コメント 1 件 ·
-
難易度 3/5 1〜2日 初心者へのやさしさ 67/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
ionic-team/capacitor-camera#76 · コメント 1 件 · リアクション 1 件 ·
ionic-team/capacitor-camera の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
shoelace-style/webawesome#2979 ·
メンテナーはふだん 1 日以内に返信
-
Chip source filter and denial markers miss Storage rows when a Storage activity source is pickedオープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 77/100
omdsh-dev/DSH-better-sidebar#1141 ·
メンテナーはふだん 2 日以内に返信