diff --git a/apps/mobile/lib/imagePicker.ts b/apps/mobile/lib/imagePicker.ts new file mode 100644 index 0000000..9bc97a8 --- /dev/null +++ b/apps/mobile/lib/imagePicker.ts @@ -0,0 +1,48 @@ +import * as ImagePicker from 'expo-image-picker'; + +export interface PickedImage { + uri: string; + mimeType: string; + sizeBytes: number; + width: number; + height: number; +} + +// Pick an image from the photo library. Requests permission on demand; +// returns null on cancel / denial. +export async function pickFromLibrary(): Promise { + const perm = await ImagePicker.requestMediaLibraryPermissionsAsync(); + if (!perm.granted) return null; + const res = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.Images, + quality: 0.85, + base64: false, + exif: false, + }); + if (res.canceled || res.assets.length === 0) return null; + return toPicked(res.assets[0]!); +} + +// Capture an image via the device camera. Same return shape as +// pickFromLibrary so call sites can stay shape-agnostic. +export async function captureFromCamera(): Promise { + const perm = await ImagePicker.requestCameraPermissionsAsync(); + if (!perm.granted) return null; + const res = await ImagePicker.launchCameraAsync({ + quality: 0.85, + base64: false, + exif: false, + }); + if (res.canceled || res.assets.length === 0) return null; + return toPicked(res.assets[0]!); +} + +function toPicked(asset: ImagePicker.ImagePickerAsset): PickedImage { + return { + uri: asset.uri, + mimeType: asset.mimeType ?? 'image/jpeg', + sizeBytes: asset.fileSize ?? 0, + width: asset.width, + height: asset.height, + }; +}