Skip to main content

Working with Image Manipulation (expo-image-manipulator)

1. Resizing Images

Property Description Values
resize Resize options for the image { width: number, height: number }
format Output format of the image 'jpeg' | 'png' | 'webp'
quality Quality of the output image (0-100) number

Example: Resizing an Image

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'https://example.com/image.jpg';
const resizeOptions = {
  resize: { width: 300, height: 200 },
  format: 'jpeg',
  quality: 80,
};

manipulateAsync(imageUri, [resizeOptions])
  .then(result => {
    console.log('Resized image URI:', result.uri);
  })
  .catch(error => {
    console.error('Error resizing image:', error);
  });

2. Cropping Images

Property Description Values
crop Crop configuration object { originX: number, originY: number, width: number, height: number }
resize Resize configuration object { width: number, height: number }
format Output image format 'jpeg' | 'png'

Example: Cropping an Image

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'file:///path/to/image.jpg';
const cropConfig = {
  originX: 50,
  originY: 50,
  width: 200,
  height: 200
};

manipulateAsync({
  uri: imageUri,
  crop: cropConfig
}).then(result => {
  console.log('Cropped image URI:', result.uri);
});

3. Rotating Images

Property Description Values
rotate Rotation angle in degrees 0, 90, 180, 270

Example: Rotating an Image

import { manipulateAsync } from 'expo-image-manipulator';

const rotateImage = async () => {
  const result = await manipulateAsync(
    'https://example.com/image.jpg',
    [{ rotate: 90 }],
    { compress: 0.8, format: 'jpeg' }
  );
  console.log(result.uri);
};

rotateImage();

4. Flipping Images

Option Values Description
flipHorizontal true | false Flip the image horizontally (left-right)
flipVertical true | false Flip the image vertically (top-bottom)

Example: Flip Image Horizontally

import { manipulateAsync } from 'expo-image-manipulator';

const flipImage = async () => {
  const result = await manipulateAsync(
    'https://example.com/image.jpg',
    [{ flipHorizontal: true }],
    { compress: 0.8, format: 'jpeg' }
  );
  console.log(result.uri);
};

flipImage();

Example: Flip Image Vertically

import { manipulateAsync } from 'expo-image-manipulator';

const flipImage = async () => {
  const result = await manipulateAsync(
    'https://example.com/image.jpg',
    [{ flipVertical: true }],
    { compress: 0.8, format: 'jpeg' }
  );
  console.log(result.uri);
};

flipImage();

Example: Flip Image Both Ways

import { manipulateAsync } from 'expo-image-manipulator';

const flipImage = async () => {
  const result = await manipulateAsync(
    'https://example.com/image.jpg',
    [
      { flipHorizontal: true },
      { flipVertical: true }
    ],
    { compress: 0.8, format: 'jpeg' }
  );
  console.log(result.uri);
};

flipImage();

5. Saving Manipulated Images

Property Description Values
saveAsync Saves the manipulated image to the local filesystem function(options?: SaveOptions): Promise<SaveResult>

Example: Saving an Image

import { manipulateAsync } from 'expo-image-manipulator';
import { saveAs } from 'expo-file-system';

const imageUri = 'https://example.com/image.jpg';
const saveOptions = {
  format: 'jpeg',
  quality: 0.8,
  compress: true
};

manipulateAsync({
  uri: imageUri,
  actions: [{ resize: { width: 300, height: 300 } }]
}).then(result => {
  return saveAs(result.uri, 'manipulated-image.jpg');
}).then(() => {
  console.log('Image saved successfully');
});
Note: The image must be saved to the local filesystem using expo-file-system after manipulation.
Option Description Values
format Specifies the output format of the image 'jpeg' | 'png' | 'webp'
quality Compression quality (0.0 to 1.0) number
compress Enables or disables compression boolean

6. Setting Compression Level

Property Description Values Notes
quality Compression level for JPEG output 0 to 1 Higher values = better quality, larger file size. Default is 0.8.

Example: Compressing an image with low quality

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'https://example.com/image.jpg';
const actions = [
  { compress: 0.3 },
];

manipulateAsync(imageUri, actions).then((result) => {
  console.log('Compressed image URI:', result.uri);
});

7. Converting Image Formats

Format Description Notes
JPEG jpeg Lossy compression format, best for photographs
PNG png Lossless compression, supports transparency
WEBP webp Modern format with lossy and lossless options, smaller file size
GIF gif Supports animation and transparency

Example: Converting Image to JPEG

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'file:///path/to/image.png';
const saveOptions = {
  compress: 0.8,
  format: 'jpeg',
};

manipulateAsync({
  uri: imageUri,
  actions: [],
  saveFormat: 'jpeg',
  saveOptions,
}).then((result) => {
  console.log('Converted image URI:', result.uri);
});

Example: Converting Image to PNG

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'file:///path/to/image.jpg';
const saveOptions = {
  compress: 1.0,
  format: 'png',
};

manipulateAsync({
  uri: imageUri,
  actions: [],
  saveFormat: 'png',
  saveOptions,
}).then((result) => {
  console.log('Converted image URI:', result.uri);
});
Note: The format option in saveOptions determines the output image format. Supported formats are jpeg, png, webp, and gif.

8. Combining Multiple Actions

Example: Applying Multiple Transformations

import { manipulateAsync } from 'expo-image-manipulator';

const imageUri = 'file:///path/to/image.jpg';

const actions = [
  {
    resize: { width: 200, height: 200 },
  },
  {
    flip: { horizontal: true },
  },
  {
    rotate: 90,
  },
];

manipulateAsync({
  uri: imageUri,
  actions,
}).then((result) => {
  console.log('Processed image URI:', result.uri);
});
Action Parameters Description
resize { width: number, height: number } Resizes the image to specified dimensions
flip { horizontal: boolean } Flips the image horizontally or vertically
rotate number Rotates the image by specified degrees (90, 180, 270)
crop { originX: number, originY: number, width: number, height: number } Crops the image to specified rectangle
Note: Actions are applied in the order they appear in the array. The result of one action becomes input for the next.

9. Using Base64 Output

Option Values Description
base64 true When set to true, the result will be a Base64 encoded string instead of a file URI.

Example: Resize Image and Output as Base64

import { manipulateAsync } from 'expo-image-manipulator';

const resizeImageBase64 = async () => {
  const result = await manipulateAsync(
    'https://example.com/image.jpg',
    [{ resize: { width: 200, height: 200 } }],
    { base64: true }
  );

  console.log(result.base64); // Base64 string of the resized image
};

resizeImageBase64();

10. Handling Manipulation Errors

Property Description Notes
error string Error message describing the issue
code string Error code for programmatic handling

Example: Error Handling

import { manipulateAsync } from 'expo-image-manipulator';

try {
  const result = await manipulateAsync(
    { uri: 'https://example.com/image.jpg' },
    [{ resize: { width: 200, height: 200 } }],
    { compress: 0.8, format: 'jpeg' }
  );
} catch (error) {
  console.error('Manipulation failed:', error.code, error.message);
}
Note: Common error codes include MANIPULATION_FAILED, INVALID_URI, and UNSUPPORTED_FORMAT.

Was this article helpful?