The original async function API for image manipulation, deprecated as of SDK 52 in favor of the contextual API. Still supported for backward compatibility.
Legacy function that performs image manipulation operations in a single async call. All transformations are applied sequentially in the order specified.
/**
* Manipulate an image with specified actions and save options
* @param uri - URI of the image to manipulate (file://, data:, or asset URI)
* @param actions - Array of transformation actions to apply sequentially
* @param saveOptions - Configuration for saving the result image
* @returns Promise resolving to ImageResult with the manipulated image
* @deprecated Use ImageManipulator.manipulate() or useImageManipulator() instead
*/
function manipulateAsync(
uri: string,
actions?: Action[],
saveOptions?: SaveOptions
): Promise<ImageResult>;Usage Examples:
import { manipulateAsync, SaveFormat, FlipType } from "expo-image-manipulator";
// Basic resize and rotate
const result1 = await manipulateAsync(
'file:///path/to/image.jpg',
[
{ resize: { width: 300 } },
{ rotate: 90 }
],
{ format: SaveFormat.PNG }
);
// Complex transformation pipeline
const result2 = await manipulateAsync(
'file:///path/to/image.jpg',
[
{ resize: { width: 800, height: 600 } },
{ crop: { originX: 100, originY: 50, width: 600, height: 500 } },
{ rotate: -45 },
{ flip: FlipType.Horizontal }
],
{
format: SaveFormat.JPEG,
compress: 0.8,
base64: true
}
);
// No actions (just format conversion)
const result3 = await manipulateAsync(
'file:///path/to/image.png',
[],
{ format: SaveFormat.JPEG, compress: 0.9 }
);Union type representing all possible transformation actions that can be applied in the legacy API.
/**
* Union type of all possible transformation actions
*/
type Action = ActionResize | ActionRotate | ActionFlip | ActionCrop | ActionExtent;Resize transformation that changes image dimensions with optional aspect ratio preservation.
/**
* Resize action for changing image dimensions
*/
interface ActionResize {
resize: {
/** Target width in pixels. If omitted, calculated from height to preserve aspect ratio */
width?: number;
/** Target height in pixels. If omitted, calculated from width to preserve aspect ratio */
height?: number;
};
}Usage Examples:
// Resize to exact dimensions
const result1 = await manipulateAsync(imageUri, [
{ resize: { width: 400, height: 300 } }
]);
// Resize width only (preserve aspect ratio)
const result2 = await manipulateAsync(imageUri, [
{ resize: { width: 500 } }
]);
// Resize height only (preserve aspect ratio)
const result3 = await manipulateAsync(imageUri, [
{ resize: { height: 400 } }
]);Rotation transformation that rotates the image by a specified angle in degrees.
/**
* Rotate action for rotating images by degrees
*/
interface ActionRotate {
/** Rotation angle in degrees. Positive for clockwise, negative for counter-clockwise */
rotate: number;
}Usage Examples:
// Rotate 90 degrees clockwise
const result1 = await manipulateAsync(imageUri, [
{ rotate: 90 }
]);
// Rotate 45 degrees counter-clockwise
const result2 = await manipulateAsync(imageUri, [
{ rotate: -45 }
]);
// Rotate 180 degrees
const result3 = await manipulateAsync(imageUri, [
{ rotate: 180 }
]);Flip transformation that mirrors the image vertically or horizontally.
/**
* Flip action for mirroring images
*/
interface ActionFlip {
/** Direction to flip the image */
flip: FlipType;
}Usage Examples:
import { FlipType } from "expo-image-manipulator";
// Flip horizontally (mirror left-right)
const result1 = await manipulateAsync(imageUri, [
{ flip: FlipType.Horizontal }
]);
// Flip vertically (mirror top-bottom)
const result2 = await manipulateAsync(imageUri, [
{ flip: FlipType.Vertical }
]);
// Using string values
const result3 = await manipulateAsync(imageUri, [
{ flip: 'horizontal' }
]);
// Flip both ways (requires two separate actions)
const result4 = await manipulateAsync(imageUri, [
{ flip: FlipType.Horizontal },
{ flip: FlipType.Vertical }
]);Crop transformation that extracts a rectangular region from the image.
/**
* Crop action for extracting rectangular regions
*/
interface ActionCrop {
crop: {
/** X coordinate of the top-left corner of the crop rectangle */
originX: number;
/** Y coordinate of the top-left corner of the crop rectangle */
originY: number;
/** Width of the crop rectangle in pixels */
width: number;
/** Height of the crop rectangle in pixels */
height: number;
};
}Usage Examples:
// Crop from top-left corner
const result1 = await manipulateAsync(imageUri, [
{ crop: { originX: 0, originY: 0, width: 300, height: 300 } }
]);
// Crop from center (assuming 800x600 original)
const result2 = await manipulateAsync(imageUri, [
{ crop: { originX: 200, originY: 150, width: 400, height: 300 } }
]);
// Crop after resize
const result3 = await manipulateAsync(imageUri, [
{ resize: { width: 1000 } },
{ crop: { originX: 100, originY: 100, width: 800, height: 600 } }
]);Extent transformation that places the image on a larger or smaller canvas with background fill.
/**
* Extent action for changing canvas size with background fill
* @platform web
*/
interface ActionExtent {
extent: {
/** Background color for unfilled areas (CSS color string or null for transparent) */
backgroundColor?: string | null;
/** X position of the image on the new canvas */
originX?: number;
/** Y position of the image on the new canvas */
originY?: number;
/** Width of the new canvas */
width: number;
/** Height of the new canvas */
height: number;
};
}Usage Examples:
// Extend to larger canvas with white background
const result1 = await manipulateAsync(imageUri, [
{ extent: { width: 800, height: 600, backgroundColor: '#FFFFFF' } }
]);
// Position image on canvas
const result2 = await manipulateAsync(imageUri, [
{ extent: {
width: 1000,
height: 800,
originX: 100,
originY: 150,
backgroundColor: 'transparent'
}}
]);
// Combine with other operations
const result3 = await manipulateAsync(imageUri, [
{ resize: { width: 300 } },
{ extent: {
width: 500,
height: 500,
originX: 100,
originY: 100,
backgroundColor: '#F0F0F0'
}}
]);The legacy manipulateAsync function can be easily replaced with the modern contextual API:
// Legacy API
const result = await manipulateAsync(
imageUri,
[
{ resize: { width: 300 } },
{ rotate: 90 },
{ flip: 'horizontal' }
],
{ format: SaveFormat.PNG, compress: 0.8 }
);
// Modern API equivalent
const context = ImageManipulator.manipulate(imageUri);
const image = await context
.resize({ width: 300 })
.rotate(90)
.flip('horizontal')
.renderAsync();
const result = await image.saveAsync({
format: SaveFormat.PNG,
compress: 0.8
});
// Clean up memory
context.release();
image.release();// React Hook equivalent
function ImageProcessor({ imageUri }: { imageUri: string }) {
const context = useImageManipulator(imageUri);
const processImage = async () => {
const image = await context
.resize({ width: 300 })
.rotate(90)
.flip('horizontal')
.renderAsync();
const result = await image.saveAsync({
format: SaveFormat.PNG,
compress: 0.8
});
// Only need to clean up the rendered image
image.release();
return result;
};
// Context cleanup is automatic
}import { manipulateAsync, SaveFormat, FlipType } from "expo-image-manipulator";
async function processImageLegacy(imageUri: string) {
try {
// Complex transformation with multiple actions
const result = await manipulateAsync(
imageUri,
[
// First resize to manageable size
{ resize: { width: 800 } },
// Crop to remove unwanted areas
{ crop: { originX: 50, originY: 100, width: 700, height: 500 } },
// Rotate for proper orientation
{ rotate: 90 },
// Flip horizontally for mirroring effect
{ flip: FlipType.Horizontal }
],
{
format: SaveFormat.JPEG,
compress: 0.8,
base64: false
}
);
console.log(`Processed image: ${result.uri}`);
console.log(`Final size: ${result.width}x${result.height}`);
return result;
} catch (error) {
console.error('Image processing failed:', error);
throw error;
}
}