Skip to content

oguzhnatly/react-native-image-manipulator

ย 
ย 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

75 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ–ผ react-native-image-manipulator

Crop, rotate, flip, and resize images in React Native without Expo or Unimodules. Fully typed. Built on the same API as expo-image-manipulator so it feels familiar, but works in any bare React Native project.

npm version npm downloads license platforms


Why this package?

Most image manipulation libraries for React Native either require Expo or pull in a heavy dependency tree through Unimodules. This package is a standalone drop-in that gives you the same clean, chainable API without any of that overhead. Crop, rotate, flip, resize, compress and export to JPEG or PNG in a single call.


Features

  • โœ… No Expo or Unimodules dependency
  • โœ… Full TypeScript support with typed actions and return values
  • โœ… Works on iOS and Android
  • โœ… Crop, rotate, flip, and resize in a single invocation
  • โœ… Chain multiple transformations in one call
  • โœ… JPEG and PNG output formats
  • โœ… Optional Base64 output alongside the file URI
  • โœ… Configurable compression level

Installation

npm install @oguzhnatly/react-native-image-manipulator
yarn add @oguzhnatly/react-native-image-manipulator

iOS Setup

Install native pods after adding the package:

cd ios && pod install

Mostly Automatic Installation (React Native < 0.60)

react-native link @oguzhnatly/react-native-image-manipulator

Android Setup

No additional setup required for Android on React Native 0.60+. The package links automatically via autolinking.

Manual Linking (React Native < 0.60)

iOS

  1. In Xcode, right click Libraries and select Add Files to [your project]
  2. Navigate to node_modules/@oguzhnatly/react-native-image-manipulator and add RNImageManipulator.xcodeproj
  3. In your project target, go to Build Phases โ†’ Link Binary With Libraries and add libRNImageManipulator.a

Android

Add the following to android/settings.gradle:

include ':react-native-image-manipulator'
project(':react-native-image-manipulator').projectDir = new File(rootProject.projectDir, '../node_modules/@oguzhnatly/react-native-image-manipulator/android')

Add the following to the dependencies block in android/app/build.gradle:

implementation project(':react-native-image-manipulator')

Open android/app/src/main/java/[...]/MainActivity.java and add:

import com.oguzhnatly.rnimagemanipulator.RNImageManipulatorPackage;

Then register the package inside getPackages():

new RNImageManipulatorPackage()

Usage

Basic Example

import RNImageManipulator from '@oguzhnatly/react-native-image-manipulator';

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ rotate: 90 }, { flip: { vertical: true } }],
  { format: 'png' }
);

console.log(result.uri);    // URI of the output image
console.log(result.width);  // Output image width
console.log(result.height); // Output image height

Resize with Aspect Ratio Preserved

Provide only one dimension and the other is calculated automatically:

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ resize: { width: 800 } }],
  { format: 'jpeg', compress: 0.9 }
);

Crop to a Specific Region

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ crop: { originX: 50, originY: 50, width: 400, height: 400 } }],
  { format: 'jpeg', compress: 1 }
);

Multiple Transformations in One Call

Actions are applied in the order they are provided:

const result = await RNImageManipulator.manipulate(
  imageUri,
  [
    { rotate: 90 },
    { flip: { horizontal: true } },
    { resize: { width: 600 } },
    { crop: { originX: 0, originY: 0, width: 600, height: 400 } },
  ],
  { format: 'jpeg', compress: 0.85, base64: true }
);

// result.base64 is available when base64: true
const dataUri = `data:image/jpeg;base64,${result.base64}`;

API

RNImageManipulator.manipulate(uri, actions, saveOptions)

Applies a sequence of transformations to the image at uri and writes the result to a new file. The source file is never modified.

Parameters

Parameter Type Required Description
uri string Yes URI of the source image. Must be within app scope
actions Action[] Yes Ordered array of transformations to apply
saveOptions SaveOptions Yes Output format, compression level, and base64 flag

Action Types

resize

{ resize: { width?: number; height?: number } }

Resizes the image. If only one dimension is provided, the other is computed automatically to preserve the original aspect ratio.

rotate

{ rotate: number }

Rotates the image by the given number of degrees. Positive values rotate clockwise, negative values rotate counter-clockwise.

flip

{ flip: { vertical?: boolean; horizontal?: boolean } }

Flips the image along the specified axis or axes. Both can be set to true at the same time.

crop

{ crop: { originX: number; originY: number; width: number; height: number } }

Crops the image to a rectangle. originX and originY define the top-left corner of the crop area in pixels relative to the current image size.

Save Options

Option Type Default Description
format 'jpeg' | 'png' 'jpeg' Output format. PNG is lossless. JPEG produces smaller files with compression artifacts
compress number (0 to 1) 1 Compression amount. 1 means no compression. 0 is maximum compression. Only applies to JPEG
base64 boolean false When true, the result includes a base64 string of the output image

Return Value

{
  uri: string;      // URI to the output image file
  width: number;    // Width of the output image in pixels
  height: number;   // Height of the output image in pixels
  base64?: string;  // Base64 encoded image data, present only when saveOptions.base64 is true
}

Prepend data:image/jpeg;base64, or data:image/png;base64, to the base64 value to construct a data URI usable directly in an <Image> source.


Notes

  • Each call to manipulate always produces a new file. Passing the same URI as input and overwriting is not supported due to how React Native caches images.
  • Actions are applied sequentially in the order provided. The output of each action becomes the input for the next.
  • Rotation that is not a multiple of 90 degrees may introduce transparent padding on iOS depending on the image dimensions.

Changelog

See CHANGELOG.md for release history.


License

MIT ยฉ Oguzhan Atalay

Packages

 
 
 

Contributors

Languages

  • Java 37.4%
  • Objective-C 31.3%
  • TypeScript 7.8%
  • Ruby 7.5%
  • Kotlin 6.9%
  • JavaScript 4.6%
  • Objective-C++ 4.5%