react-native-nitro-image-marker
High-performance image watermarking for React Native. Add text overlays, image stamps, tile watermarks, crop, blur, apply filters, and batch process — all natively on iOS and Android.
Hero Screenshot / Demo GIF
Recommended: 800x400px showing before/after watermark result
Features
- Text watermarks — color, font, size, bold, italic, underline, shadow, background, rotation, alpha, maxWidth
- Image watermarks — overlay logos/stamps with position, scale, rotation, alpha
- Combined watermarks — text + image overlays in a single call
- Tile watermarks — repeating diagonal text or image patterns across the entire image
- Crop — extract a rectangular region before watermarking
- Image filters — brightness, contrast, grayscale
- Blur regions — blur specific rectangular areas (faces, sensitive info)
- Batch processing — process multiple images in one native call
- URL image loading — load images from remote URLs (http/https)
- Output formats — PNG, JPG, or base64
- Cross-platform — iOS (Swift) and Android (Kotlin)
Installation
Install the packages
npm install react-native-nitro-image-marker react-native-nitro-modulesInstall iOS Pods
cd ios && pod install && cd ..Import and use
import { markText, ImageFormat, Position } from 'react-native-nitro-image-marker'npx expo prebuild + dev client. See Expo Setup.Requirements
| Property | Type | Description |
|---|---|---|
React Native | >= 0.76.0 | Minimum supported version |
react-native-nitro-modules | >= 0.35.2 | Required peer dependency |
Node.js | >= 18.0.0 | Runtime requirement |
Quick Start
Add a simple text watermark to an image:
import { markText, ImageFormat, Position } from 'react-native-nitro-image-marker'
const filePath = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [
{
text: 'Sample Watermark',
position: { position: Position.bottomRight, X: 16, Y: 16 },
style: {
color: '#FFFFFF',
fontSize: 24,
bold: true,
},
},
],
saveFormat: ImageFormat.png,
})Promise<string>. Always use await or .then().Quick Start Result Screenshot
Show a photo with 'Sample Watermark' text at bottom-right
Methods
markText()
Add one or more text watermarks to an image. Supports crop, filters, blur, and tile patterns.
Returns: Promise<string> — file path (PNG/JPG) or base64 string
const result = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [
{
text: 'CONFIDENTIAL',
position: { position: Position.center },
style: {
color: '#FF0000',
fontSize: 32,
bold: true,
rotate: -25,
alpha: 0.5,
},
},
],
saveFormat: ImageFormat.png,
})markImage()
Add image overlays and optional text watermarks to an image. Supports all processing features.
Returns: Promise<string> — file path or base64 string
const result = await markImage({
backgroundImage: { image: photoUri },
watermarkImages: [
{
src: logoUri,
position: { position: Position.bottomRight, X: 16, Y: 16 },
scale: 0.25,
alpha: 0.8,
},
],
watermarkTexts: [
{
text: 'Brand Name',
position: { position: Position.topCenter, Y: 20 },
style: { color: '#FFFFFF', fontSize: 20, bold: true },
},
],
saveFormat: ImageFormat.png,
})markTextBatch()New
Process multiple text watermark operations in a single native call. More efficient than calling markText() in a loop.
Returns: Promise<string[]> — array of file paths or base64 strings
const results = await markTextBatch([
{
backgroundImage: { image: photo1Uri },
watermarkTexts: [{ text: 'Photo 1', position: { position: Position.center } }],
saveFormat: ImageFormat.jpg,
},
{
backgroundImage: { image: photo2Uri },
watermarkTexts: [{ text: 'Photo 2', position: { position: Position.center } }],
saveFormat: ImageFormat.jpg,
},
])markImageBatch()New
Process multiple image watermark operations in a single native call.
Returns: Promise<string[]> — array of file paths or base64 strings
Options & Types
Options for markText() and each item in markTextBatch().
| Property | Type | Description |
|---|---|---|
backgroundImagereq | ImageOptions | Source image to watermark |
watermarkTextsreq | TextOptions[] | Array of text overlays |
quality | number | JPG quality 0-1 |
filename | string | Output filename (no extension) |
saveFormat | ImageFormat | Output format: jpg, png, or base64 |
maxSize | number | Max longest edge in px (downscales) |
crop | CropOptions | Crop region before watermarking |
filter | FilterOptions | Image filter adjustments |
blurRegions | BlurRegion[] | Rectangular areas to blur |
tile | TileOptions | Repeating tile watermark pattern |
Options for markImage(). Same as TextMarkOptions plus image overlays.
| Property | Type | Description |
|---|---|---|
backgroundImagereq | ImageOptions | Source image to watermark |
watermarkImagesreq | WatermarkImageOptions[] | Array of image overlays |
watermarkTexts | TextOptions[] | Optional text overlays |
quality | number | JPG quality 0-1 |
filename | string | Output filename (no extension) |
saveFormat | ImageFormat | Output format |
maxSize | number | Max longest edge in px |
crop | CropOptions | Crop region before watermarking |
filter | FilterOptions | Image filter adjustments |
blurRegions | BlurRegion[] | Rectangular areas to blur |
tile | TileOptions | Repeating tile watermark pattern |
Configuration for the background/source image.
| Property | Type | Description |
|---|---|---|
imagereq | ImageSource | Local path, file:// URI, http(s):// URL, or bundled asset via require() |
scale | number | Scale factor before processing (e.g. 0.5 = half size) |
rotate | number | Rotation in degrees |
alpha | number | Opacity 0-1 |
quality | number | JPG quality 0-1 |
Configuration for each text watermark overlay.
| Property | Type | Description |
|---|---|---|
textreq | string | Text content to render |
position | PositionOptions | Position and offset |
style | TextStyle | Text styling options |
Full text styling: font, color, shadow, background, stroke, rotation, and more.
| Property | Type | Description |
|---|---|---|
color | string | Text color (hex, e.g. '#FFFFFF') |
fontName | string | Font family name |
fontSize | number | Size in px |
bold | boolean | Bold text |
italic | boolean | Italic text |
underline | boolean | Underline decoration |
strikeThrough | boolean | Strikethrough decoration |
textAlign | TextAlign | Text alignment: left, center, right |
rotate | number | Rotation in degrees |
skewX | number | Horizontal skew in degrees |
alpha | number | Text opacity 0-1 |
maxWidth | number | Max text width in px (enables wrapping) |
shadow | ShadowLayerStyle | Drop shadow settings |
shadowStyle | ShadowLayerStyle | Shadow settings (alias for shadow) |
backgroundColor | string | Simple background color behind text |
textBackgroundStyle | TextBackgroundStyle | Advanced background with padding & radius |
strokeColor | string | Text outline/stroke color |
strokeWidth | number | Text outline/stroke width |
Advanced background styling behind text with padding and corner radius.
| Property | Type | Description |
|---|---|---|
type | TextBackgroundType | Background mode: none, stretchX, stretchY, cornerRadius |
color | string | Background color (hex) |
cornerRadius | RadiusValue | Per-corner radii |
cornerRadiusAll | number | Uniform corner radius |
padding | Dimension | All sides padding |
paddingLeft | Dimension | Left padding |
paddingTop | Dimension | Top padding |
paddingRight | Dimension | Right padding |
paddingBottom | Dimension | Bottom padding |
paddingHorizontal | Dimension | Left + right padding |
paddingVertical | Dimension | Top + bottom padding |
Drop shadow configuration for text watermarks.
| Property | Type | Description |
|---|---|---|
shadowRadiusreq | number | Blur radius |
shadowDxreq | number | Horizontal offset |
shadowDyreq | number | Vertical offset |
shadowColorreq | string | Shadow color (hex) |
Configuration for each image overlay (logo, stamp, etc.).
| Property | Type | Description |
|---|---|---|
srcreq | ImageSource | Watermark image: local path, URL, or bundled asset |
position | PositionOptions | Position and offset |
scale | number | Scale factor (e.g. 0.25 = 25% of original) |
rotate | number | Rotation in degrees |
alpha | number | Opacity 0-1 |
Anchor position with optional X/Y offsets. Offsets can be numbers (px) or strings.
| Property | Type | Description |
|---|---|---|
position | Position | Anchor: topLeft, topCenter, topRight, center, bottomLeft, bottomCenter, bottomRight |
X | Dimension | Horizontal offset (number in px or string) |
Y | Dimension | Vertical offset (number in px or string) |
Define a rectangular crop region. Cropping is applied before watermarks are drawn.
| Property | Type | Description |
|---|---|---|
xreq | number | X origin of crop rectangle |
yreq | number | Y origin of crop rectangle |
widthreq | number | Crop width in px |
heightreq | number | Crop height in px |
Apply image filter adjustments. Filters are applied before watermarks are drawn.
| Property | Type | Description |
|---|---|---|
brightness | number | Brightness adjustment (-1 to 1). 0 = no change. |
contrast | number | Contrast multiplier (0.5 to 2.0). 1 = no change. |
grayscale | boolean | Convert to grayscale |
Define a rectangular area to blur. Great for hiding faces, license plates, or personal data.
| Property | Type | Description |
|---|---|---|
xreq | number | X origin |
yreq | number | Y origin |
widthreq | number | Region width in px |
heightreq | number | Region height in px |
blurRadius | number | Blur intensity (default: 10) |
Repeating tile watermark pattern across the entire image. Specify either tileText or tileImage (not both).
| Property | Type | Description |
|---|---|---|
tileText | TextOptions | Text to repeat as a tile |
tileImage | WatermarkImageOptions | Image to repeat as a tile |
spacing | number | Space between tiles in px |
angle | number | Tile rotation angle in degrees (e.g. -30) |
Per-corner radius for text background styling.
| Property | Type | Description |
|---|---|---|
topLeft | number | Top-left corner radius |
topRight | number | Top-right corner radius |
bottomLeft | number | Bottom-left corner radius |
bottomRight | number | Bottom-right corner radius |
Enums
Position
Anchor position for watermark placement.
Position.topLeftPosition.topCenterPosition.topRightPosition.centerPosition.bottomLeftPosition.bottomCenterPosition.bottomRightPosition Grid Diagram
Visual showing all 7 anchor positions on a photo
ImageFormat
Output format for the processed image.
ImageFormat.jpgfile pathImageFormat.pngfile pathImageFormat.base64base64 stringTextAlign
Text alignment within the watermark.
TextAlign.leftTextAlign.centerTextAlign.rightTextBackgroundType
Background mode for text watermarks.
noneNo backgroundstretchXFull widthstretchYFull heightcornerRadiusRounded boxTextBackgroundType Comparison
Side-by-side showing none, stretchX, stretchY, cornerRadius
Feature Guides
Text Watermarks
Add styled text overlays with full control over font, color, size, shadow, background, rotation, opacity, and more.
const result = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [
{
text: 'Paid',
position: { position: Position.topRight, X: 16, Y: 16 },
style: {
color: '#FFFFFF',
fontSize: 24,
bold: true,
shadow: { shadowRadius: 6, shadowDx: 0, shadowDy: 3, shadowColor: '#000000AA' },
textBackgroundStyle: {
type: TextBackgroundType.cornerRadius,
color: '#1E9D5A',
paddingHorizontal: 12,
paddingVertical: 6,
cornerRadiusAll: 8,
},
},
},
],
saveFormat: ImageFormat.jpg,
quality: 0.9,
})Text Watermark Result
Show a 'Paid' badge with green background on a photo
Image Overlays
Overlay logos, stamps, or other images with position, scale, rotation, and alpha control.
const result = await markImage({
backgroundImage: { image: photoUri },
watermarkImages: [
{
src: logoUri,
position: { position: Position.topLeft, X: 16, Y: 16 },
scale: 0.2,
alpha: 0.9,
},
],
watermarkTexts: [
{
text: 'Order #5521',
position: { position: Position.bottomLeft, X: 16, Y: 16 },
style: { color: '#FFFFFF', fontSize: 22, bold: true },
},
],
saveFormat: ImageFormat.jpg,
})Image Overlay Result
Show a photo with logo at top-left and text at bottom
Tile Watermarks
Repeat a text or image pattern diagonally across the entire image. Perfect for "DRAFT", "CONFIDENTIAL", or brand watermarks.
const result = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [],
tile: {
tileText: {
text: 'DRAFT',
style: { color: '#FF000033', fontSize: 24, bold: true },
},
spacing: 120,
angle: -30,
},
saveFormat: ImageFormat.png,
})Tile Watermark Result
Show 'DRAFT' repeated diagonally across a photo
Cropping
Extract a rectangular region from the image before applying watermarks.
const result = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [
{ text: 'Cropped', position: { position: Position.bottomRight, X: 8, Y: 8 } },
],
crop: { x: 100, y: 100, width: 400, height: 300 },
saveFormat: ImageFormat.jpg,
})Crop Result
Show before (full image) and after (cropped region)
Image Filters
Apply brightness, contrast, and grayscale adjustments. Filters are applied before watermarks.
// Grayscale
const bw = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [{ text: 'B&W', position: { position: Position.center } }],
filter: { grayscale: true },
saveFormat: ImageFormat.jpg,
})
// Brightness + Contrast
const enhanced = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [{ text: 'Enhanced', position: { position: Position.center } }],
filter: { brightness: 0.2, contrast: 1.3 },
saveFormat: ImageFormat.jpg,
})Filter Results
Side-by-side: original, grayscale, enhanced brightness/contrast
Blur Regions
Blur specific rectangular areas to hide sensitive information like faces, license plates, or personal data.
const result = await markText({
backgroundImage: { image: photoUri },
watermarkTexts: [
{ text: 'Redacted', position: { position: Position.topLeft, X: 16, Y: 16 } },
],
blurRegions: [
{ x: 50, y: 200, width: 300, height: 100, blurRadius: 25 },
],
saveFormat: ImageFormat.jpg,
})Blur Region Result
Show a photo with a blurred rectangular area
Batch Processing
Process multiple images in a single native call. More efficient than sequential markText() calls in a loop.
const results = await markTextBatch([
{
backgroundImage: { image: photo1Uri },
watermarkTexts: [
{ text: 'Photo 1 of 3', position: { position: Position.bottomLeft, X: 16, Y: 16 } },
],
saveFormat: ImageFormat.jpg,
},
{
backgroundImage: { image: photo2Uri },
watermarkTexts: [
{ text: 'Photo 2 of 3', position: { position: Position.bottomLeft, X: 16, Y: 16 } },
],
saveFormat: ImageFormat.jpg,
},
])
// results is string[] — one file path per input
console.log(`Processed ${results.length} images`)URL Image Loading
Load images directly from remote URLs. Both background and watermark images support http:// and https:// URLs.
const result = await markImage({
backgroundImage: { image: 'https://example.com/photo.jpg' },
watermarkImages: [
{
src: 'https://example.com/logo.png',
position: { position: Position.topLeft, X: 16, Y: 16 },
scale: 0.2,
},
],
saveFormat: ImageFormat.png,
})Expo Setup
This package requires native code. Expo Go is not supported. Use prebuild + dev client.
Install packages
npx expo install react-native-nitro-image-marker react-native-nitro-modulesPrebuild native projects
npx expo prebuild --cleanRun dev client
npx expo run:ios
# or
npx expo run:androidSaving to Gallery
The library only renders watermarks. Saving to the device gallery is your responsibility.
React Native CLI (CameraRoll)
import { CameraRoll } from '@react-native-camera-roll/camera-roll'
const uri = filePath.startsWith('file://') ? filePath : `file://${filePath}`
await CameraRoll.saveAsset(uri, { type: 'photo' })Expo (MediaLibrary)
import * as MediaLibrary from 'expo-media-library'
const uri = filePath.startsWith('file://') ? filePath : `file://${filePath}`
const { granted } = await MediaLibrary.requestPermissionsAsync()
if (granted) await MediaLibrary.saveToLibraryAsync(uri)Performance Tips
- Prefer JPG for large photos and tune
quality(0.7-0.9) to reduce output size. - Use maxSize to limit the longest edge and prevent memory pressure on large images.
- Scale down with
backgroundImage.scale(e.g. 0.5) for smaller output. - Use batch methods (markTextBatch / markImageBatch) when processing multiple images.
- Avoid excessive overlays on very large images. Render multiple watermarks in a single call.
- Cache downloaded images when using URL loading. Download once, then pass the local file path.
Troubleshooting
Ensure the input is a local file path/URI, http(s):// URL, or base64 string. Remote URLs are supported but must be accessible.
When using bundled assets, pass require() directly: { image: require('./asset.png') }.
The library only renders watermarks. You must save using CameraRoll or MediaLibrary. Ensure permissions are granted. Prefix with file:// if the saving library requires it.
X and Y are offsets in pixels from the anchor position. Use position for the anchor and X/Y for fine-tuning.
Use maxSize to cap the output dimensions or backgroundImage.scale to downscale before processing. See Performance Tips.
Ensure the blur coordinates are within the image bounds. If you're also using crop, note that blur coordinates are relative to the cropped image.
Expo Go is not supported. This package requires native code. Run npx expo prebuild --clean and use npx expo run:ios or npx expo run:android.