chooseFromGallery returns the original library asset (HEIC on iOS) where pickImages re-encoded to JPEG

Aperta
#69 0 commenti 4 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
55/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
swift, typescript
Ambito
mobile-dev

Direzione di ricerca

Inizia da IONCAMRPhotoLibraryService.fetchImage(from:) e dal relativo percorso fetchImageURL(for: asset), quindi esamina i rami didFinishPicking e thumbnailAsData. Confronta il comportamento di iOS con onChooseFromGalleryResult e createImageMediaResult di Android. Il lavoro è completato quando il comportamento del formato della galleria scelto è coerente con la risoluzione selezionata e la documentazione di chooseFromGallery spiega la codifica risultante.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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
  1. On an iPhone with Settings → Camera → Formats → High Efficiency, take a photo.
  2. Call chooseFromGallery({ mediaType: MediaTypeSelection.Photo, includeMetadata: true }) and pick it.
  3. results[0].metadata.format is heic, and uri points at a .HEIC file.

Expected (and what pickImages did): a JPEG.

Possible resolutions

Any one of these would be enough, in rough order of preference:

  1. Give ChooseFromGalleryOptions an encodingType like TakePhotoOptions has, and re-encode to it.
  2. Re-encode gallery picks to JPEG by default, matching the deprecated methods' behaviour.
  3. If pass-through is the intended design, say so in the chooseFromGallery docs and in the deprecation notes on getPhoto/pickImages — the format change is the migration's sharpest edge and currently isn't mentioned.
Lingua principale
TypeScript
Stelle
6
Fork
3
Merge medio
2g 21h
PR unite (30g)
4

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di ionic-team/capacitor-camera

Tutte le issue di ionic-team/capacitor-camera

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.