or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

context-management.mdindex.mdlegacy-api.mdoutput.mdtransformations.md
tile.json

legacy-api.mddocs/

Legacy API (Deprecated)

The original async function API for image manipulation, deprecated as of SDK 52 in favor of the contextual API. Still supported for backward compatibility.

Capabilities

manipulateAsync Function

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 }
);

Action Types

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;

ActionResize

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 } }
]);

ActionRotate

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 }
]);

ActionFlip

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 }
]);

ActionCrop

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 } }
]);

ActionExtent (Web Only)

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'
  }}
]);

Migration to Modern API

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
}

Complete Example

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;
  }
}