onPapernitro-image-markerv0.2.0
Built with Nitro Modules

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.

VersionDownloadsLicense
Text Watermarks
Image Overlays
Tile Patterns
Crop Regions
Blur Areas
Image Filters
Batch Processing
URL Loading

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

1

Install the packages

Terminal
npm install react-native-nitro-image-marker react-native-nitro-modules
2

Install iOS Pods

Terminal
cd ios && pod install && cd ..
3

Import and use

TypeScript
import { markText, ImageFormat, Position } from 'react-native-nitro-image-marker'
Expo Users
This package requires native code. Expo Go is not supported. Use npx expo prebuild + dev client. See Expo Setup.

Requirements

PropertyTypeDescription
React Native>= 0.76.0Minimum supported version
react-native-nitro-modules>= 0.35.2Required peer dependency
Node.js>= 18.0.0Runtime requirement

Quick Start

Add a simple text watermark to an image:

TypeScript
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,
})
Important
All methods return Promise<string>. Always use await or .then().

Quick Start Result Screenshot

Show a photo with 'Sample Watermark' text at bottom-right

Methods

markText()

markText(options: TextMarkOptions): Promise<string>

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

TypeScript
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()

markImage(options: ImageMarkOptions): Promise<string>

Add image overlays and optional text watermarks to an image. Supports all processing features.

Returns: Promise<string> — file path or base64 string

TypeScript
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

markTextBatch(optionsArray: TextMarkOptions[]): Promise<string[]>

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

TypeScript
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

markImageBatch(optionsArray: ImageMarkOptions[]): Promise<string[]>

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().

PropertyTypeDescription
backgroundImagereqImageOptionsSource image to watermark
watermarkTextsreqTextOptions[]Array of text overlays
qualitynumberJPG quality 0-1
filenamestringOutput filename (no extension)
saveFormatImageFormatOutput format: jpg, png, or base64
maxSizenumberMax longest edge in px (downscales)
cropCropOptionsCrop region before watermarking
filterFilterOptionsImage filter adjustments
blurRegionsBlurRegion[]Rectangular areas to blur
tileTileOptionsRepeating tile watermark pattern

Options for markImage(). Same as TextMarkOptions plus image overlays.

PropertyTypeDescription
backgroundImagereqImageOptionsSource image to watermark
watermarkImagesreqWatermarkImageOptions[]Array of image overlays
watermarkTextsTextOptions[]Optional text overlays
qualitynumberJPG quality 0-1
filenamestringOutput filename (no extension)
saveFormatImageFormatOutput format
maxSizenumberMax longest edge in px
cropCropOptionsCrop region before watermarking
filterFilterOptionsImage filter adjustments
blurRegionsBlurRegion[]Rectangular areas to blur
tileTileOptionsRepeating tile watermark pattern

Configuration for the background/source image.

PropertyTypeDescription
imagereqImageSourceLocal path, file:// URI, http(s):// URL, or bundled asset via require()
scalenumberScale factor before processing (e.g. 0.5 = half size)
rotatenumberRotation in degrees
alphanumberOpacity 0-1
qualitynumberJPG quality 0-1

Configuration for each text watermark overlay.

PropertyTypeDescription
textreqstringText content to render
positionPositionOptionsPosition and offset
styleTextStyleText styling options

Full text styling: font, color, shadow, background, stroke, rotation, and more.

PropertyTypeDescription
colorstringText color (hex, e.g. '#FFFFFF')
fontNamestringFont family name
fontSizenumberSize in px
boldbooleanBold text
italicbooleanItalic text
underlinebooleanUnderline decoration
strikeThroughbooleanStrikethrough decoration
textAlignTextAlignText alignment: left, center, right
rotatenumberRotation in degrees
skewXnumberHorizontal skew in degrees
alphanumberText opacity 0-1
maxWidthnumberMax text width in px (enables wrapping)
shadowShadowLayerStyleDrop shadow settings
shadowStyleShadowLayerStyleShadow settings (alias for shadow)
backgroundColorstringSimple background color behind text
textBackgroundStyleTextBackgroundStyleAdvanced background with padding & radius
strokeColorstringText outline/stroke color
strokeWidthnumberText outline/stroke width

Advanced background styling behind text with padding and corner radius.

PropertyTypeDescription
typeTextBackgroundTypeBackground mode: none, stretchX, stretchY, cornerRadius
colorstringBackground color (hex)
cornerRadiusRadiusValuePer-corner radii
cornerRadiusAllnumberUniform corner radius
paddingDimensionAll sides padding
paddingLeftDimensionLeft padding
paddingTopDimensionTop padding
paddingRightDimensionRight padding
paddingBottomDimensionBottom padding
paddingHorizontalDimensionLeft + right padding
paddingVerticalDimensionTop + bottom padding

Drop shadow configuration for text watermarks.

PropertyTypeDescription
shadowRadiusreqnumberBlur radius
shadowDxreqnumberHorizontal offset
shadowDyreqnumberVertical offset
shadowColorreqstringShadow color (hex)

Configuration for each image overlay (logo, stamp, etc.).

PropertyTypeDescription
srcreqImageSourceWatermark image: local path, URL, or bundled asset
positionPositionOptionsPosition and offset
scalenumberScale factor (e.g. 0.25 = 25% of original)
rotatenumberRotation in degrees
alphanumberOpacity 0-1

Anchor position with optional X/Y offsets. Offsets can be numbers (px) or strings.

PropertyTypeDescription
positionPositionAnchor: topLeft, topCenter, topRight, center, bottomLeft, bottomCenter, bottomRight
XDimensionHorizontal offset (number in px or string)
YDimensionVertical offset (number in px or string)

Define a rectangular crop region. Cropping is applied before watermarks are drawn.

PropertyTypeDescription
xreqnumberX origin of crop rectangle
yreqnumberY origin of crop rectangle
widthreqnumberCrop width in px
heightreqnumberCrop height in px

Apply image filter adjustments. Filters are applied before watermarks are drawn.

PropertyTypeDescription
brightnessnumberBrightness adjustment (-1 to 1). 0 = no change.
contrastnumberContrast multiplier (0.5 to 2.0). 1 = no change.
grayscalebooleanConvert to grayscale

Define a rectangular area to blur. Great for hiding faces, license plates, or personal data.

PropertyTypeDescription
xreqnumberX origin
yreqnumberY origin
widthreqnumberRegion width in px
heightreqnumberRegion height in px
blurRadiusnumberBlur intensity (default: 10)

Repeating tile watermark pattern across the entire image. Specify either tileText or tileImage (not both).

PropertyTypeDescription
tileTextTextOptionsText to repeat as a tile
tileImageWatermarkImageOptionsImage to repeat as a tile
spacingnumberSpace between tiles in px
anglenumberTile rotation angle in degrees (e.g. -30)

Per-corner radius for text background styling.

PropertyTypeDescription
topLeftnumberTop-left corner radius
topRightnumberTop-right corner radius
bottomLeftnumberBottom-left corner radius
bottomRightnumberBottom-right corner radius

Enums

Position

Anchor position for watermark placement.

Position.topLeft
Position.topCenter
Position.topRight
Position.center
Position.bottomLeft
Position.bottomCenter
Position.bottomRight

Position Grid Diagram

Visual showing all 7 anchor positions on a photo

ImageFormat

Output format for the processed image.

ImageFormat.jpgfile path
ImageFormat.pngfile path
ImageFormat.base64base64 string

TextAlign

Text alignment within the watermark.

TextAlign.left
TextAlign.center
TextAlign.right

TextBackgroundType

Background mode for text watermarks.

noneNo background
stretchXFull width
stretchYFull height
cornerRadiusRounded box

TextBackgroundType 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.

TypeScript
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.

TypeScript
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.

TypeScript
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.

TypeScript
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.

TypeScript
// 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.

TypeScript
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.

TypeScript
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.

TypeScript
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,
})
Tip
URL loading downloads the image each time. For repeated use, download once and pass the local file path for better performance.

Expo Setup

This package requires native code. Expo Go is not supported. Use prebuild + dev client.

1

Install packages

Terminal
npx expo install react-native-nitro-image-marker react-native-nitro-modules
2

Prebuild native projects

Terminal
npx expo prebuild --clean
3

Run dev client

Terminal
npx expo run:ios
# or
npx expo run:android

Saving to Gallery

The library only renders watermarks. Saving to the device gallery is your responsibility.

React Native CLI (CameraRoll)

TypeScript
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)

TypeScript
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.