Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

expo-images-picker

natysoz2.4kISC2.5.1

Expo images picker, Selecting Multiple images and videos from user device

expo, images, images-picker, images picker, multiple images, images selector, media selector, picker, videos, imagepicker, multiple, Media Library

readme

expo-images-picker

Multiple Asset Photos | Videos selecting package for Expo SDK 43+. For users who use React native and managed workflow + Styled Components.

MediaLibrary.

Image-manipulator.

styled-components

Test permissions with SDK 47 working without issues.

Best Practice just watch the video or Copy the snack :)

How to Video => https://youtu.be/xcMcVZTw6xA

Copy & Paste => https://snack.expo.dev/@natysoz/expo-images-picker

Features

  • expo multiple image selector
  • Allow selecting multiple Photos or Videos.
  • Allow getting extra metadata.
  • Allow resizing and get base64 images.
  • Permission requests built in.
  • Support Both landscape and portrait.
  • Simple Indicator for the selected Assets.
  • Custom Indicator for the selected Assets.
  • Allow using custom navbar component.
  • Optimized for speed.

Sample Sample

Usage

  1. Install with

     $ npm install expo-images-picker

    or

     $ yarn add expo-images-picker

    then

     $ expo install expo-image-manipulator expo-media-library
  2. import to the top of your file like

     import { AssetsSelector } from 'expo-images-picker'
  3. install @expo-vectors package and send icons as props to the widget
     import { Ionicons } from '@expo/vector-icons'
  4. Use the imported as Following =>
     <AssetsSelector
        Settings={widgetSettings}
        Errors={widgetErrors}
        Styles={widgetStyles}
        Resize={widgetResize}       // optional
        Navigator={widgetNavigator} // optional
        CustomNavigator={{          // optional
             Component: CustomNavigator,
             props: {
                 backFunction: true,
                 onSuccess,
                 text: T.ACTIONS.SELECT,
            },
         }}
      />

[📚 Params]

Settings :

you better create this const out of your component , if you do need it inside your component , use useMemo from react.

    const widgetSettings = useMemo(
        () => ({
            getImageMetaData: false,
            initialLoad: 100,
            assetsType: [MediaType.photo, MediaType.video],
            minSelection: 1,
            maxSelection: 3,
            existingSelectionIds: ["<selected Id 1>", "<selected Id 2>", "<selected Id N>"],
            portraitCols: 4,
            landscapeCols: 4,
        }),
        []
    )
  • getImageMetaData - return an asset with extra metadata fields * may cause slower results .

    but on some ios versions its a must , because u need the absolute file path file:// and not asset-library://

  • initialLoad - initial amount of assets to load first time.
  • assetsType - array that includes [MediaType.photo, MediaType.video]. [photo , video ].
  • minSelection - min amount of images user need to select.
  • maxSelection - max amount of images user need to select.
  • existingSelectionIds - array that includes the id's of those assets previously selected. Each value comes from the Asset in onSuccess callback. optional
  • portraitCols - Number of columns in portrait Mode.
  • landscapeCols - Number of columns in landscape Mode.

Errors :

    const widgetErrors = useMemo(
        () => ({
            errorTextColor: polar_text_2,
            errorMessages: {
                hasErrorWithPermissions: translator(
                    T.ERROR.HAS_PERMISSIONS_ERROR
                ),
                hasErrorWithLoading: translator(T.ERROR.HAS_INTERNAL_ERROR),
                hasErrorWithResizing: translator(T.ERROR.HAS_INTERNAL_ERROR),
                hasNoAssets: translator(T.ERROR.HAS_NO_ASSETS),
            },
        }),
        []
    )
  • onError - callback function that you can pass and will fire whenever there is an error.

  • errorTextColor - set the text color of an error message.

  • errorMessages

    `hasErrorWithPermissions`- error text when there are no permissions.
    `hasErrorWithLoading` - error text for issue with loading assets.
    `hasErrorWithResizing` - error text for issue with resizing.
    `hasNoAssets` - text shows when there are no assets to show.

Styles :

    const widgetStyles = useMemo(
        () => ({
            margin: 2,
            bgColor: bg,
            spinnerColor: main,
            widgetWidth: 99,
            screenStyle:{
                borderRadius: 5,
                overflow: "hidden",
            },
            widgetStyle:{
                margin: 10
            },
            videoIcon: {
                Component: Ionicons,
                iconName: 'ios-videocam',
                color: polar_text_1,
                size: 20,
            },
            selectedIcon: {
                Component: Ionicons,
                iconName: 'ios-checkmark-circle-outline',
                color: 'white',
                bg: mainWithOpacity,
                size: 26,
            },
        }),
        [polar_text_1, mainWithOpacity]
    )
  • margin - set margin between the images.
  • bgColor - set the widget background color.
  • spinnerColor - set the color of the spinner (loading indicator).
  • widgetWidth - the widget width in percentages .

  • screenStyle (Optional) - set the style of the Screen wrapping both Navigator and Widget.

  • widgetStyle (Optional) - set the style of the Widget wrapping the AssetList (contains all the images, videos,etc)
  • videoIcon
`Component` - the icon component.(from @expo/vector-icons).
`iconName` -  the icon name.
`Component` - the icon color.
`Component` - the icon size.
  • selectedIcon - the widget width in percentages .
`Component` - the icon component.(from @expo/vector-icons).
`iconName` -  the icon name.
`color` - the icon color.
`bg` - set the cover color when an asset is select.
`size` - the icon size.
    const widgetNavigator = useMemo(
        () => ({
            Texts: {
                finish: 'finish',
                back: 'back',
                selected: 'selected',
            },
            midTextColor: polar_text_2,
            minSelection: 3,
            buttonTextStyle: _textStyle,
            buttonStyle: _buttonStyle,
            onBack: () => navigation.goBack(),
            onSuccess: (data: Asset[]) => onSuccess(data),
        }),
        []
    )
  • Texts - send in finish back selected texts.

  • midTextColor - set the color of the middle text aka "selected" .

  • minSelection - set the min selection , continue button will be unavailable until user select this amount of images.

  • buttonTextStyle - Text Style Object , design the text inside the buttons.

  • buttonStyle - View Style Object, design the button itself.

  • onBack - Send in a function to go back to your screen.

  • onSuccess - Send in a function to go back and send the returned data.

Resize :

    const widgetResize = useMemo(
        () => ({
            width: 512,
            height: 384,
            majorAxis: 512,
            compress: 0.7,
            base64: false,
            saveTo: SaveType.JPG,
        }),
        []
    )

**Note that using manipulate might result with crash or slow loading times on older phones.

  • All fields are optional , in order to resize and keep images Ratio its recommend sending only width or height, and it will resize using this axis only.

  • width - Manipulate image width optional

  • height - Manipulate image width optional

  • majorAxis - Manipulate image's major axis only (if width and height are not specified) optional

  • compress - compress 0.1 Super low quality 1.0 leave as is (high quality).

  • base64 - will add extra result , image as a base64 string.

  • saveTo - can be png or jpeg .

CustomNavigator :

Make sure your CustomTopNavigator can receive onSuccess function. And bind this onFinish function on the correct button. This is useful for integrating with React Navigation header.

  • Component - Send in your Custom nav bar.

  • props Send any props your Custom Component needs.

Example with React Navigation

type CustomNavImageSelectionProps = {
  navigation: CustomNavigationProp
  onSuccess: () => void
  backFunction: boolean
  text: string
};

function CustomNavImageSelection({ navigation, onSuccess, backFunction, text }: CustomNavImageSelectionProps) {
  useEffect(() => {
    navigation.setOptions({
      headerRight: () => <Button title={text} onPress={onSuccess} />,
    })
  }, [navigation, onSuccess, text])

  return null
}

<AssetsSelector
  options={{
    ...otherProps,
    CustomTopNavigator: {
      Component: CustomNavImageSelection,
      props: {
        navigation,
        onSuccess: (data: Asset[]) => {
            onDone(data)
            navigation.goBack()
        },
        backFunction: true,
        text: T.ACTIONS.SELECT
      },
    },
  }}
/>

changelog

Changelog


🛠 Breaking changes


2.4.0 — 2022-05-22

  • upgrade using expo sdk 45 to fix permissions issue.

2.1.0 — 2022-03-24

  • refactor widget deps to support SDK 44.0.0+.

2.1.0 — 2021-10-30

  • refactor widget deps to support SDK 43+.

2.0.0 — 2021-07-24

  • refactor widget props see README.MD.
  • expo SDK 42 Support.
  • update version for some packages to stay updated.
  • add option to retrieve assets Metadata (Exif, LocalUri and more...).
  • add the option to send minSelection for default top navigator.
  • add option to bind selected length for your custom top navigator.

1.4.0 — 2021-06-03

  • expo permissions package removed.
  • update version for some packages to stay updated.

1.3.2 — 2021-04-12

  • defaultTopNavigator props changed

you now have buttonTextStyle and buttonStyle and midTextColor

-buttonTextStyle - send style to design the text inside the button -buttonStyle - send style to design the button itself -midTextColor - send color to override middle text color

1.3.1 — 2021-02-04

  • add option to override selected text on default top navigator.

1.3.1 — 2021-02-04

  • now options and all fields become mandatory field.

1.3.0 — 2021-02-04

  • Add spinnerColor attribute

1.1.0 — 2020-06-12

  • Removed ['buttonBgColor','buttonTextColor','midTextColor'] props from DefaultNavigator

🎉 New features


2.4.1 - 2022-05-22

  • add button to open settings when there are no permissions.

2.2.5 - 2022-01-08

  • add mediaType to modAssets on returning selected resized image.

2.2.4 - 2021-11-12

  • add screenStyle and widgetStyle to Styles and StylesType

2.0.0 — 2021-07-24

  • expo SDK 42 Support.
  • add option to retrieve assets Metadata (Exif, LocalUri and more...).
  • add the option to send minSelection for default top navigator.
  • add option to bind selected length for your custom top navigator.

1.4.1 — 2021-04-12

  • Add initialLoad to define how many images to load first time.

1.3.1 — 2021-04-12

  • Add selectedText to default navigator

1.3.0 — 2021-02-04

  • Add Resize , Compress and Base64 Support
  • Add Expo Image Manipulator
  • Add Spinner component shows while Manipulating images.

1.2.0 — 2021-01-10

  • Update dependencies to support expo 40

1.1.0 — 2020-06-12

  • Add Style prop to style DefaultNavigator.
  • Add onError prop will fire whenever there is error loading Assets.

1.0.7 — 2020-10-25

  • You can send simple component instead of icon components , to display numbers on top of the images (instead of icon)

for example:

const SelectedIcon = ({size,index,color}: SelectedIconProps) => <Text style={{color:color,fontSize:size}}>{index + 1}</Text>

Type should look like type SelectedIconProps = { iconName:string, color:string, bg:string, size:number index:number}

And just send this simple component on "selectedIcon" when using the widget

selectedIcon: { Component: SelectedIcon, iconName: '', color: 'white', bg: '#ffffff90', size: 22}

🐛 Bug fixes


2.2.3 - 2021-08-11

  • fix Compile error with typescript

2.2.2 — 2021-05-11

  • fix Compile error with the latest PR.

2.1.2 — 2021-05-10

  • fix Compile error typescript 4.3.5 issue with skipLibCheck.

1.1.0 — 2020-06-12

  • "after" field Parse was fixed on Expo SDK 39 , it's now working smoothly on Android and IOS.
  • Fix design bug , if you had less than 4 images in total , widget center it and its looking not correct, so align-items:center removed

1.0.7 — 2020-10-25

_Request from "hypnocapybara" Was Merged (#1)

  • Remove Immutable dependency

1.0.6 — 2020-09-27

_Update to Expo SDK 39 is now required , they fix the issue with parse error on the "after" field

_Still they have issue with an asset that is not valid "Asset", images that users manually put on the Gallery folder may cause the app to close without any error.

_Request from the team to help on issue (#10398)

🐛 Known Bugs


  • Images and Videos that users manually put on the Gallery can crash the app without any error especially Telegram images and videos. Expo Media library is very buggy.

Upcoming


  • Add an option to select images base on albums