as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

expo-image-manipulator

@amazon-devices/expo-image-manipulator provides an API to modify images stored on the local file system.

Installation

  1. Add the JavaScript library dependency in the package.json file.

    Copied to clipboard.

     "dependencies": {
          ...
         "@amazon-devices/expo-image-manipulator": "~2.0.0",
         "@amazon-devices/keplerscript-turbomodule-api": "~1.0.0",
         ...
     }
    
  2. Reinstall dependencies using npm install command.

Examples

The following example demonstrates how to perform a single manipulation on the image.

Copied to clipboard.


import * as ImageManipulator from '@amazon-devices/expo-image-manipulator';
import React, {useState, useEffect} from 'react';
import {Button, Image, StyleSheet, View} from 'react-native';

type ImageType = {
  uri: string;
  localUri?: string;
};

export const App = () => {
  const [ready, setReady] = useState(false);
  const [image, setImage] = useState<ImageType | null>(null);

  useEffect(() => {
    (async () => {
      const image = require('./assets/kepler.png');
      const imageUri = Image.resolveAssetSource(image).uri;
      setImage({uri: imageUri});
      setReady(true);
    })();
  }, []);

  const manipulate = async () => {
    if (image) {
      const result = await ImageManipulator.manipulateAsync(
        image.localUri || image.uri,
        [{flip: ImageManipulator.FlipType.Vertical}],
      );
      setImage(result);
    }
  };

  const renderImage = () => (
    <View style={styles.imageContainer}>
      {image != null && (
        <Image
          source={{uri: image.localUri || image.uri}}
          style={styles.image}
        />
      )}
    </View>
  );

  return (
    <View style={styles.container}>
      {ready && image && renderImage()}
      <Button title="Manipulate" onPress={manipulate} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  imageContainer: {
    marginVertical: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: 300,
    height: 300,
    resizeMode: 'contain',
  },
});

The following example demonstrates how to perform multiple manipulations on the image.

Copied to clipboard.


import * as ImageManipulator from '@amazon-devices/expo-image-manipulator';
import React, {useState, useEffect} from 'react';
import {Button, Image, StyleSheet, View} from 'react-native';

type ImageType = {
  uri: string;
  localUri?: string;
};

export const App = () => {
  const [ready, setReady] = useState(false);
  const [image, setImage] = useState<ImageType | null>(null);

  useEffect(() => {
    (async () => {
      const image = require('./assets/kepler.png');
      const imageUri = Image.resolveAssetSource(image).uri;
      setImage({uri: imageUri});
      setReady(true);
    })();
  }, []);

  const manipulate = async () => {
    if (image) {
      const result = await ImageManipulator.manipulateAsync(image.uri, [
        {flip: ImageManipulator.FlipType.Vertical},
        {rotate: 90},
      ]);
      setImage({uri: result.uri});
    }
  };

  const renderImage = () => (
    <View style={styles.imageContainer}>
      {!!image && <Image source={{uri: image.uri}} style={styles.image} />}
    </View>
  );

  return (
    <View style={styles.container}>
      {ready && image && renderImage()}
      <Button title="Manipulate" onPress={manipulate} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  imageContainer: {
    marginVertical: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: 300,
    height: 300,
    resizeMode: 'contain',
  },
});

The following example demonstrates how to specify custom save options.

Copied to clipboard.


import * as ImageManipulator from '@amazon-devices/expo-image-manipulator';
import React, {useState, useEffect} from 'react';
import {Button, Image, StyleSheet, Text, View} from 'react-native';

type ImageType = {
  uri: string;
  localUri?: string;
};

export const App = () => {
  const [ready, setReady] = useState(false);
  const [image, setImage] = useState<ImageType | null>(null);
  const [base64, setBase64] = useState<string>();

  useEffect(() => {
    (async () => {
      const image = require('./assets/kepler.png');
      const imageUri = Image.resolveAssetSource(image).uri;
      setImage({uri: imageUri});
      setReady(true);
    })();
  }, []);

  const manipulate = async () => {
    if (image) {
      const result = await ImageManipulator.manipulateAsync(
        image.localUri || image.uri,
        [{rotate: 90}],
        {
          base64: true,
          compress: 0.5,
          format: ImageManipulator.SaveFormat.PNG,
        },
      );
      setImage({
        uri: result.uri,
        localUri: result.uri,
      });
      setBase64(result.base64);
    }
  };

  const renderImage = () => (
    <View style={styles.imageContainer}>
      {image && (
        <Image
          source={{uri: image.localUri || image.uri}}
          style={styles.image}
        />
      )}
    </View>
  );

  return (
    <View style={styles.container}>
      {ready && image && renderImage()}
      <Button title="Manipulate" onPress={manipulate} />
      <Text style={styles.text}>{`Base64: ${
        base64 ? base64.slice(0, 30) : 'None'
      }`}</Text>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  imageContainer: {
    marginVertical: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  image: {
    width: 300,
    height: 300,
    resizeMode: 'contain',
  },
  text: {
    fontSize: 32,
    color: 'white',
  },
});

API reference

Check out the dedicated documentation page for info about this library, API reference and more: Official Expo documentation for expo-image-manipulator.

Methods

Method Description
manipulateAsync Manipulate the image provided via uri. Available modifications are rotating, flipping (mirroring), resizing and cropping. Each invocation results in a new file. With one invocation you can provide a set of actions to perform over the image. Overwriting the source file would not have an effect in displaying the result as images are cached

Known issues and limitations

With saveOptions.compress, compress doesn't work on kepler. Images are always saved with the highest quality (as if value 1.0 was passed).

Supported versions

Package Version Based On @amazon-devices/react-native-kepler version
2.0.x 11.6.0 2.0.x

For information on additional libraries, see Supported Third-Party Libraries and Services.


Last updated: Sep 30, 2025