react-native-image-crop-picker vs react-native-image-marker vs react-native-image-resizer
React Native Image Manipulation Libraries
react-native-image-crop-pickerreact-native-image-markerreact-native-image-resizerSimilar Packages:

React Native Image Manipulation Libraries

react-native-image-crop-picker, react-native-image-marker, and react-native-image-resizer are specialized React Native libraries for handling images, each addressing distinct aspects of image manipulation. react-native-image-crop-picker provides a native UI for selecting images from the device gallery or camera, with built-in support for cropping, rotation, and compression. react-native-image-marker enables adding text or image watermarks to existing images by overlaying content at specified coordinates. react-native-image-resizer focuses exclusively on resizing and compressing images to specific dimensions or quality levels without any user interface. Together, they cover common mobile image processing needs — from user selection to post-processing — but serve non-overlapping primary purposes.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-native-image-crop-picker06,3412.2 MB6464 months agoMIT
react-native-image-marker0361283 kB14a month agoMIT
react-native-image-resizer01,659-55 years agoMIT

Image Handling in React Native: Crop Picker vs Marker vs Resizer

When building mobile apps with React Native, you often need to handle images — whether it’s letting users select and crop photos, adding watermarks or text overlays, or resizing large images for performance. The three packages react-native-image-crop-picker, react-native-image-marker, and react-native-image-resizer each solve distinct but sometimes overlapping problems in this space. Let’s break down what they do, how they differ, and when to use which.

📸 Core Purpose: What Each Package Actually Does

react-native-image-crop-picker is a user-facing image picker with built-in cropping and compression. It lets users choose photos from their gallery or take new ones with the camera, then optionally crop, rotate, or compress them before returning the result.

// Example: Open image picker with cropping
import ImagePicker from 'react-native-image-crop-picker';

const image = await ImagePicker.openPicker({
  width: 300,
  height: 400,
  cropping: true,
  compressImageQuality: 0.8
});
// Returns { path, width, height, mime, size }

react-native-image-marker focuses on adding overlays to existing images — like text, watermarks, or custom drawings — and saving the modified image. It does not handle image selection or user interaction.

// Example: Add text watermark to an image
import ImageMarker from 'react-native-image-marker';

const markedImage = await ImageMarker.markText({
  src: '/path/to/image.jpg',
  text: '© My App',
  X: 20,
  Y: 20,
  color: '#ffffff',
  fontSize: 16
});
// Returns path to new image file

react-native-image-resizer is purely about resizing and compressing existing images to reduce file size or fit specific dimensions. It doesn’t provide UI or overlay capabilities.

// Example: Resize image to max width/height
import ImageResizer from 'react-native-image-resizer';

const resizedImage = await ImageResizer.createResizedImage(
  '/path/to/image.jpg',
  400,    // maxWidth
  400,    // maxHeight
  'JPEG', // format
  80      // quality (0–100)
);
// Returns { uri, width, height, name, size }

🎯 User Interaction vs. Background Processing

This is the biggest architectural distinction.

  • react-native-image-crop-picker is the only one that opens native UI (camera or photo library). It’s meant for direct user interaction.
  • react-native-image-marker and react-native-image-resizer operate silently on existing image paths. They assume you already have an image URI (e.g., from a picker, download, or cache).

💡 If your app needs users to select images, you’ll likely start with react-native-image-crop-picker. Then, if you need to add a watermark or further resize, you’d pass its output to one of the other two.

🔧 Feature Comparison: Cropping, Marking, and Resizing

Cropping Support

Only react-native-image-crop-picker supports interactive cropping:

// react-native-image-crop-picker
const cropped = await ImagePicker.openCropper({
  path: '/existing/image.jpg',
  width: 200,
  height: 200
});

Neither react-native-image-marker nor react-native-image-resizer can crop images. They only resize proportionally or to fit bounds.

Adding Overlays (Text/Watermarks)

Only react-native-image-marker supports this:

// react-native-image-marker
await ImageMarker.markText({
  src: imageUri,
  text: 'CONFIDENTIAL',
  X: 50,
  Y: 100,
  fontName: 'Arial-BoldMT',
  fontSize: 24
});

The other two packages have no overlay capabilities whatsoever.

Resizing and Compression

All three can resize and compress, but with different trade-offs:

  • react-native-image-crop-picker: Resizing/compression happens during selection. You can’t reprocess an existing image without re-picking.

    // Only during openPicker/openCamera
    await ImagePicker.openPicker({
      width: 500,
      height: 500,
      compressImageMaxWidth: 1000,
      compressImageQuality: 0.7
    });
    
  • react-native-image-resizer: Built specifically for this. Offers fine control over output format (JPEG, PNG, WEBP) and quality.

    const resized = await ImageResizer.createResizedImage(
      uri, 800, 600, 'PNG', 90
    );
    
  • react-native-image-marker: Can resize while marking, but it’s not its primary purpose. Less control over output format.

    // Scaling during markText
    await ImageMarker.markText({
      src: uri,
      scale: 0.5, // optional resize factor
      // ... other options
    });
    

⚙️ Platform-Specific Considerations

All three require native modules and must be linked (or auto-linked via CocoaPods/Gradle). However:

  • react-native-image-crop-picker has the most complex native setup due to camera/gallery permissions and UI components. On iOS, you must add usage descriptions in Info.plist.
  • react-native-image-resizer and react-native-image-marker are simpler — they only process files, so no runtime permissions beyond storage access.

Also note: react-native-image-marker uses native drawing APIs (Canvas on Android, Core Graphics on iOS), so text rendering may look slightly different across platforms.

🔄 Typical Workflow Integration

In real apps, these tools are often chained together:

  1. Use react-native-image-crop-picker to let the user select and crop a profile picture.
  2. Pass the resulting image to react-native-image-resizer to ensure it’s under 1MB for upload.
  3. Optionally, use react-native-image-marker to add a timestamp or logo before saving.
// Combined example
const picked = await ImagePicker.openPicker({
  cropping: true,
  width: 400,
  height: 400
});

const resized = await ImageResizer.createResizedImage(
  picked.path, 400, 400, 'JPEG', 80
);

const watermarked = await ImageMarker.markText({
  src: resized.uri,
  text: 'Uploaded via MyApp',
  X: 10,
  Y: resized.height - 30
});

🛑 Maintenance and Compatibility Notes

As of mid-2024:

  • react-native-image-crop-picker is actively maintained and compatible with React Native 0.72+.
  • react-native-image-resizer is also actively maintained, with recent updates for modern React Native versions.
  • react-native-image-marker appears less actively updated, but still functions correctly on current React Native versions. No official deprecation notice exists, but verify compatibility with your target platform versions.

None of these packages are deprecated, but always test on your target iOS and Android versions.

📊 When to Use Which?

NeedBest Package
Let users pick/crop photos from gallery or camerareact-native-image-crop-picker
Add text/logo watermarks to existing imagesreact-native-image-marker
Reduce image file size or fit to dimensionsreact-native-image-resizer
Do all of the above in sequenceChain all three

💡 Final Recommendation

Don’t think of these as competitors — they’re complementary tools for different stages of image handling:

  • Start with react-native-image-crop-picker if you need user input.
  • Reach for react-native-image-resizer when you need reliable, format-aware resizing.
  • Use react-native-image-marker only when you must embed visible metadata (text, logos) into images.

Trying to force one package to do another’s job leads to awkward workarounds. Instead, combine them where needed — the performance cost of multiple processing steps is usually acceptable for user-facing image workflows.

How to Choose: react-native-image-crop-picker vs react-native-image-marker vs react-native-image-resizer

  • react-native-image-crop-picker:

    Choose react-native-image-crop-picker when your app requires users to select images from their device gallery or capture new photos with the camera, especially if you need built-in cropping, rotation, or on-the-fly compression during selection. It’s the only option among the three that provides native UI interaction, making it essential for user-driven image input flows.

  • react-native-image-marker:

    Choose react-native-image-marker when you need to programmatically add visible overlays—such as text watermarks, copyright notices, or logo stamps—to existing images. It does not handle image selection or resizing as its main function, so it’s best used after an image has already been acquired through another method.

  • react-native-image-resizer:

    Choose react-native-image-resizer when your primary goal is to reduce image file size or adjust dimensions for performance, storage, or upload constraints. It offers precise control over output format (JPEG, PNG, WEBP) and quality, and works silently on existing image URIs without any UI components.

README for react-native-image-crop-picker

react-native-image-crop-picker

Backers on Open Collective Sponsors on Open Collective

iOS/Android image picker with support for camera, video, configurable compression, multiple images and cropping

Result

Important notes

  • If you are using react-native new architecture, you have to use react-native-image-crop-picker version >= 0.50.0

Usage

Import library

import ImagePicker from "react-native-image-crop-picker";

Select from gallery

Call single image picker with cropping

ImagePicker.openPicker({
  width: 300,
  height: 400,
  cropping: true,
}).then((image) => {
  console.log(image);
});

Call multiple image picker

ImagePicker.openPicker({
  multiple: true,
}).then((images) => {
  console.log(images);
});

Select video only from gallery

ImagePicker.openPicker({
  mediaType: "video",
}).then((video) => {
  console.log(video);
});

Android: The prop 'cropping' has been known to cause videos not to be displayed in the gallery on Android. Please do not set cropping to true when selecting videos.

Select from camera

Image

ImagePicker.openCamera({
  width: 300,
  height: 400,
  cropping: true,
}).then((image) => {
  console.log(image);
});

Video

ImagePicker.openCamera({
  mediaType: "video",
}).then((image) => {
  console.log(image);
});

Crop picture

ImagePicker.openCropper({
  path: "my-file-path.jpg",
  width: 300,
  height: 400,
}).then((image) => {
  console.log(image);
});

Optional cleanup

Module is creating tmp images which are going to be cleaned up automatically somewhere in the future. If you want to force cleanup, you can use clean to clean all tmp files, or cleanSingle(path) to clean single tmp file.

ImagePicker.clean()
  .then(() => {
    console.log("removed all tmp images from tmp directory");
  })
  .catch((e) => {
    alert(e);
  });

Request Object

PropertyTypeDescription
croppingbool (default false)Enable or disable cropping
widthnumberWidth of result image when used with cropping option
heightnumberHeight of result image when used with cropping option
multiplebool (default false)Enable or disable multiple image selection
writeTempFile (ios only)bool (default true)When set to false, does not write temporary files for the selected images. This is useful to improve performance when you are retrieving file contents with the includeBase64 option and don't need to read files from disk.
includeBase64bool (default false)When set to true, the image file content will be available as a base64-encoded string in the data property. Hint: To use this string as an image source, use it like: <Image source={{uri: `data:${image.mime};base64,${image.data}`}} />
includeExifbool (default false)Include image exif data in the response
avoidEmptySpaceAroundImage (ios only)bool (default true)When set to true, the image will always fill the mask space.
cropperActiveWidgetColor (android only)string (default "#424242")When cropping image, determines ActiveWidget color.
cropperStatusBarLight (android only)bool (default true)When cropping image, true for light status bar (dark icons), false for dark status bar (light icons).
cropperNavigationBarLight (android only)bool (default false)When cropping image, true for light navigation bar (dark icons), false for dark navigation bar (light icons).
cropperToolbarColor (android only)string (default #424242)When cropping image, determines the color of Toolbar.
cropperToolbarWidgetColor (android only)string (default darker orange)When cropping image, determines the color of Toolbar text and buttons.
freeStyleCropEnabledbool (default false)Enables user to apply custom rectangle area for cropping
cropperToolbarTitlestring (default Edit Photo)When cropping image, determines the title of Toolbar.
cropperCircleOverlaybool (default false)Enable or disable circular cropping mask.
disableCropperColorSetters (android only)bool (default false)When cropping image, disables the color setters for cropping library.
minFiles (ios only)number (default 1)Min number of files to select when using multiple option
maxFilesnumber (default 5)Max number of files to select when using multiple option
waitAnimationEnd (ios only)bool (default true)Promise will resolve/reject once ViewController completion block is called
smartAlbums (ios only)array (supported values) (default ['UserLibrary', 'PhotoStream', 'Panoramas', 'Videos', 'Bursts'])List of smart albums to choose from
useFrontCamerabool (default false)Whether to default to the front/'selfie' camera when opened. Please note that not all Android devices handle this parameter, see issue #1058
compressVideoPreset (ios only)string (default MediumQuality)Choose which preset will be used for video compression
compressImageMaxWidthnumber (default none)Compress image with maximum width
compressImageMaxHeightnumber (default none)Compress image with maximum height
compressImageQualitynumber (default 1 (Android)/0.8 (iOS))Compress image with quality (from 0 to 1, where 1 is best quality). On iOS, values larger than 0.8 don't produce a noticeable quality increase in most images, while a value of 0.8 will reduce the file size by about half or less compared to a value of 1.
loadingLabelText (ios only)string (default "Processing assets...")Text displayed while photo is loading in picker
mediaTypestring (default any)Accepted mediaType for image selection, can be one of: 'photo', 'video', or 'any'
showsSelectedCount (ios only)bool (default true)Whether to show the number of selected assets
sortOrder (ios only)string (default 'none', supported values: 'asc', 'desc', 'none')Applies a sort order on the creation date on how media is displayed within the albums/detail photo views when opening the image picker
forceJpg (ios only)bool (default false)Whether to convert photos to JPG. This will also convert any Live Photo into its JPG representation
showCropGuidelines (android only)bool (default true)Whether to show the 3x3 grid on top of the image during cropping
showCropFrame (android only)bool (default true)Whether to show crop frame during cropping
hideBottomControls (android only)bool (default false)Whether to display bottom controls
enableRotationGesture (android only)bool (default false)Whether to enable rotating the image by hand gesture
cropperChooseText (ios only)string (default choose)Choose button text
cropperChooseColor (ios only)string (default #FFCC00)HEX format color for the Choose button. Default color is controlled by TOCropViewController.
cropperCancelText (ios only)string (default Cancel)Cancel button text
cropperCancelColor (ios only)string (default tint iOS color )HEX format color for the Cancel button. Default value is the default tint iOS color controlled by TOCropViewController
cropperRotateButtonsHidden (ios only)bool (default false)Enable or disable cropper rotate buttons

Smart Album Types (ios)

NOTE: Some of these types may not be available on all iOS versions. Be sure to check this to avoid issues.

['PhotoStream', 'Generic', 'Panoramas', 'Videos', 'Favorites', 'Timelapses', 'AllHidden', 'RecentlyAdded', 'Bursts', 'SlomoVideos', 'UserLibrary', 'SelfPortraits', 'Screenshots', 'DepthEffect', 'LivePhotos', 'Animated', 'LongExposure']

Response Object

PropertyTypeDescription
pathstringSelected image location. This is null when the writeTempFile option is set to false.
localIdentifier(ios only)stringSelected images' localidentifier, used for PHAsset searching
sourceURL(ios only)stringSelected images' source path, do not have write access
filenamestringSelected images' filename
widthnumberSelected image width
heightnumberSelected image height
mimestringSelected image MIME type (image/jpeg, image/png)
sizenumberSelected image size in bytes
durationnumberVideo duration time in milliseconds
database64Optional base64 selected file representation
exifobjectExtracted exif data from image. Response format is platform specific
cropRectobjectCropped image rectangle (width, height, x, y)
creationDate (ios only)stringUNIX timestamp when image was created
modificationDatestringUNIX timestamp when image was last modified

Install

Step 1

npm i react-native-image-crop-picker --save

Step 2

iOS

cd ios
pod install

Step 3

iOS

Step 1

In Xcode open Info.plist and add string key NSPhotoLibraryUsageDescription with value that describes why you need access to user photos. More info here https://forums.developer.apple.com/thread/62229. Depending on what features you use, you also may need NSCameraUsageDescription and NSMicrophoneUsageDescription keys.

(Optional) Step 2 - To localize the camera / gallery / cropper text buttons

  • Open your Xcode project
  • Go to your project settings by opening the project name on the Navigation (left side)
  • Select your project in the project list
  • Should be into the Info tab and add in Localizations the language your app was missing throughout the +
  • Rebuild and you should now have your app camera and gallery with the classic ios text in the language you added.

Android

  • [Optional] If you want to use camera picker in your project, add following to app/src/main/AndroidManifest.xml

    • <uses-permission android:name="android.permission.CAMERA"/>
  • [Optional] If you want to use front camera, also add following to app/src/main/ AndroidManifest.xml

    • <uses-feature android:name="android.hardware.camera" android:required="false" />
    • <uses-feature android:name="android.hardware.camera.front" android:required="false" />

TO DO

  • [Android] Standardize multiple select
  • [Android] Video compression

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

License

MIT