packages

Image Picker

Opens the system photo picker or the camera and returns the chosen files. The library picker needs no permission because it uses the system picker. The result has the same shape as expo-image-picker.

  • pyxpo-image-picker
  • v0.1.0a1
  • Native: Swift + Kotlin
  • Like expo-image-picker

Install

Install the package into the same environment as pyxpo.

$pip install pyxpo-image-picker

Add image-picker to modules in your app config, then import it in your code.

pyproject.toml
[tool.pyxpo]
modules = ["image-picker"]
python
from pyxpo_image_picker import ImagePicker

This module has native code. After you add it, run pyxpo run or pyxpo build again so it is compiled into the app. Hot reload alone is not enough.

Platforms

iOSPHPicker and the camera
AndroidSystem picker and camera app
Desktop previewNeeds a simulator or device

Quick start

app/index.py
from pyxpo import Button, Image, View, useState
from pyxpo_image_picker import ImagePicker

def Index():
    uri, set_uri = useState(None)

    async def pick():
        res = await ImagePicker.launchImageLibraryAsync()
        if not res["canceled"]:
            set_uri(res["assets"][0]["uri"])

    return View(
        Button(title="Pick a photo", onPress=pick),
        uri and Image(source={"uri": uri}, style={"width": 240, "height": 240}),
    )

default = Index

Configuration

These options set the text iOS shows when it asks the user for access. Each has a default, so you only set the ones you want to change.

OptionInfo.plist keyDefault
cameraUsageDescriptionNSCameraUsageDescriptionTake photos and videos with the camera.
microphoneUsageDescriptionNSMicrophoneUsageDescriptionRecord sound with the videos you take.
pyproject.toml
[tool.pyxpo.module_options.image-picker]
cameraUsageDescription = "Take photos and videos with the camera."
microphoneUsageDescription = "Record sound with the videos you take."

Permissions

pyxpo adds these to Info.plist and AndroidManifest.xml for you when the module is listed.

iOSLibrary: none. Camera: NSCameraUsageDescription, and NSMicrophoneUsageDescription for video sound.
AndroidNone. The module uses the system camera app. If your app declares CAMERA, the module asks for it first.

API reference

ImagePicker

All methods are coroutines. snake_case names also work: launch_image_library_async and so on.

await launchImageLibraryAsync(mediaTypes="images", allowsMultipleSelection=False, selectionLimit=0)→ PickerResult

Opens the library. selectionLimit 0 means no limit and applies only with multiple selection.

await launchCameraAsync(mediaTypes="images", videoMaxDuration=0)→ PickerResult

Opens the camera. videoMaxDuration is in seconds, 0 means no limit.

await getCameraPermissionsAsync()→ Permission

Current camera permission.

await requestCameraPermissionsAsync()→ Permission

Asks the user for camera access.

Types

Results and options are plain Python dicts with these keys.

PickerResult

KeyTypeDescription
canceledboolTrue when the user closed the picker.
assetslist[Asset]The chosen files. Empty when canceled.

Asset

KeyTypeDescription
uristrfile:// URI of a copy in the app's cache folder.
type"image" | "video"
width / heightintPixels.
fileSizeintBytes.
mimeType / fileNamestr
durationintVideos only, in milliseconds.

Permission

KeyTypeDescription
statusstr"granted", "denied" or "undetermined".
granted / canAskAgainbool
expiresstr"never".

mediaTypes

KeyTypeDescription
"images"strPhotos only (default).
"videos"strVideos only.
["images", "videos"]listBoth. With the camera this is iOS only.

Examples

Pick up to five photos

Multiple selection with a limit.

python
from pyxpo_image_picker import ImagePicker

async def pick_many():
    res = await ImagePicker.launchImageLibraryAsync(
        allowsMultipleSelection=True, selectionLimit=5,
    )
    return [] if res["canceled"] else [a["uri"] for a in res["assets"]]

Record a short video

Ask for camera access, then record up to 30 seconds.

python
from pyxpo_image_picker import ImagePicker

async def record():
    perm = await ImagePicker.requestCameraPermissionsAsync()
    if not perm["granted"]:
        return None
    res = await ImagePicker.launchCameraAsync(mediaTypes="videos", videoMaxDuration=30)
    if res["canceled"]:
        return None
    clip = res["assets"][0]
    return clip["uri"], clip["duration"] / 1000   # seconds

Set the permission text

iOS shows this text when the app first opens the camera.

toml
[tool.pyxpo]
modules = ["image-picker"]

[tool.pyxpo.module_options.image-picker]
cameraUsageDescription = "Take a photo for your profile."
microphoneUsageDescription = "Record sound with your video."

Good to know

  • Photo and video in one camera capture is iOS only. On Android it raises NotSupportedError.
  • The camera fails with a clear error on a device that has no camera, such as older iOS simulators.
  • Android may close the app while the camera app is open on low memory. That capture is lost.
  • "livePhotos" is not supported and raises NotSupportedError.