npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@daboss2003/capacitor-image-marker

v1.0.0

Published

A Capacitor plugin for adding text and image watermarks to images on iOS, Android, and Web.

Readme

@daboss2003/capacitor-image-marker

A Capacitor plugin for adding text and image watermarks to images on iOS, Android, and Web.

This is a from-scratch Capacitor port of the API surface of react-native-image-marker (MIT licensed, by @JimmyDaddy). No source code from the original project is included — see NOTICE for attribution.

Install

npm install @daboss2003/capacitor-image-marker
npx cap sync

Platform requirements

| Platform | Minimum | | --- | --- | | iOS | 13.0 | | Android | SDK 22 | | Web | Any modern browser with Canvas 2D |

Example app

A working Capacitor app that exercises every feature (text watermarks, image watermarks, position presets, font size, scale, max-size, save format, etc.) lives in example/. Quick start:

cd example
npm install
npm run dev            # opens http://localhost:5173

# Native:
npx cap add ios && npm run ios
npx cap add android && npm run android

See example/README.md for details.

Image sources

Wherever an ImageOptions.src is accepted, you may pass:

  • An absolute file:// path (e.g. from @capacitor/filesystem)
  • An http:// / https:// URL
  • A data:image/...;base64,... data URI
  • A bare base64 string (will be treated as PNG/JPEG payload)

No require('./image.png') style asset references — pass real URIs.

Quick start

Mark text on an image

import {
  ImageMarker,
  Position,
  TextBackgroundType,
  ImageFormat,
} from '@daboss2003/capacitor-image-marker';

const result = await ImageMarker.markText({
  backgroundImage: {
    src: 'file:///path/to/photo.jpg',
    scale: 1,
    rotate: 0,
    alpha: 1,
  },
  watermarkTexts: [
    {
      text: 'Hello, World',
      position: { position: Position.bottomRight },
      style: {
        color: '#ffffff',
        fontSize: 36,
        fontName: 'Helvetica',
        bold: true,
        shadowStyle: {
          dx: 2,
          dy: 2,
          radius: 4,
          color: '#000000aa',
        },
        textBackgroundStyle: {
          type: TextBackgroundType.none,
          color: '#00000088',
          padding: '8 12',
          cornerRadius: {
            all: { x: 6, y: 6 },
          },
        },
      },
    },
  ],
  quality: 90,
  saveFormat: ImageFormat.jpg,
});

console.log(result.uri); // file:// path (or data: URI when saveFormat is base64)

Mark image on image

const result = await ImageMarker.markImage({
  backgroundImage: { src: 'file:///path/to/photo.jpg' },
  watermarkImages: [
    {
      src: 'file:///path/to/logo.png',
      scale: 0.5,
      alpha: 0.8,
      rotate: 0,
      position: { position: Position.bottomLeft },
    },
  ],
  saveFormat: ImageFormat.png,
});

API

ImageMarker.markText(options: TextMarkOptions): Promise<MarkResult>
ImageMarker.markImage(options: ImageMarkOptions): Promise<MarkResult>

Both methods resolve with { uri: string }:

  • For saveFormat: 'png' | 'jpg' (default jpg), uri is a file:// path to the rendered image in the app's cache directory.
  • For saveFormat: 'base64', uri is a data:image/png;base64,... data URI.

TextMarkOptions

| Field | Type | Default | Description | | --- | --- | --- | --- | | backgroundImage | ImageOptions | — | Image to draw text on. | | watermarkTexts | TextOptions[] | [] | Text watermarks to render. | | quality | number (0–100) | 100 | JPEG quality. | | filename | string | random | Output filename in cache dir. | | saveFormat | 'png' \| 'jpg' \| 'base64' | 'jpg' | Output format. | | maxSize | number | 2048 | Downscale source so neither side exceeds this. |

ImageMarkOptions

| Field | Type | Default | Description | | --- | --- | --- | --- | | backgroundImage | ImageOptions | — | Image to draw watermarks on. | | watermarkImages | WatermarkImageOptions[] | — | One or more image watermarks. | | quality | number | 100 | JPEG quality. | | filename | string | random | Output filename in cache dir. | | saveFormat | 'png' \| 'jpg' \| 'base64' | 'jpg' | Output format. | | maxSize | number | 2048 | Downscale source so neither side exceeds this. |

ImageOptions

interface ImageOptions {
  src: string;       // file:// | http(s):// | data: | bare base64
  scale?: number;    // default 1
  rotate?: number;   // degrees, default 0
  alpha?: number;    // 0..1, default 1
}

WatermarkImageOptions

Same as ImageOptions plus:

interface WatermarkImageOptions extends ImageOptions {
  position?: PositionOptions;
}

PositionOptions

Anchor a watermark either with an enum or with explicit coordinates.

interface PositionOptions {
  X?: number | string;   // px, or "10%" of background width
  Y?: number | string;   // px, or "10%" of background height
  position?: Position;   // takes precedence if set
}

enum Position {
  topLeft, topCenter, topRight,
  bottomLeft, bottomCenter, bottomRight,
  center,
}

TextOptions

interface TextOptions {
  text: string;
  position?: PositionOptions;
  style?: TextStyle;
}

TextStyle

interface TextStyle {
  color?: string;                     // CSS hex (#RGB, #RGBA, #RRGGBB, #RRGGBBAA)
  fontName?: string;
  fontSize?: number;                  // px / pt / sp
  shadowStyle?: ShadowLayerStyle | null;
  textBackgroundStyle?: TextBackgroundStyle | null;
  underline?: boolean;
  strikeThrough?: boolean;
  textAlign?: 'left' | 'center' | 'right';
  italic?: boolean;
  bold?: boolean;
  skewX?: number;                     // degrees, alternative to italic
  rotate?: number;                    // degrees around anchor
}

TextBackgroundStyle

A filled (optionally rounded) rectangle drawn behind the text.

interface TextBackgroundStyle extends Padding {
  type?: 'stretchX' | 'stretchY' | 'fit';   // default 'fit'
  color: string;
  cornerRadius?: CornerRadius;
}

Padding is CSS-like — any of these forms work:

{ padding: 10 }
{ padding: '10%' }
{ padding: '10 20' }
{ padding: '10% 20 30 40' }
{ paddingHorizontal: 12, paddingVertical: 8 }
{ paddingX: 12, paddingY: 8 }
{ paddingLeft: 8, paddingRight: 4, paddingTop: 2, paddingBottom: 2 }

CornerRadius accepts per-corner or an all shorthand:

{
  cornerRadius: {
    topLeft: { x: 8, y: 8 },
    topRight: { x: 8, y: 8 },
    all: { x: 4, y: 4 },        // applies to corners not set above
  }
}

ShadowLayerStyle

interface ShadowLayerStyle {
  dx: number;
  dy: number;
  radius: number;
  color: string;
}

Notes & caveats

  • Coordinates are expressed in pixels of the background image (after any maxSize downscaling). '10%' values are resolved relative to the parent dimension (width for X/horizontal padding, height for Y/vertical padding).
  • The default outer margin used by the enum Position values is 20px.
  • On Web the output is always a data: URI (the browser has no file system to write to). The saveFormat still controls MIME type (PNG vs JPEG).
  • iOS uses UIGraphicsImageRenderer; Android uses Bitmap + Canvas; Web uses <canvas> 2D.

License

MIT — see LICENSE and NOTICE.