<p align="center">
  <img src="https://github.com/nicholaspatten/SVGit4Me/blob/main/images/logo-lightmode.svg" alt="SVGit4Me Logo" width="200"/>
</p>

<p align="center">
  <img src="https://img.shields.io/badge/TypeScript-Ready-blue" alt="TypeScript Ready"/>
</p>

# SVGit4Me

**SVGit4Me** is a high-performance TypeScript library for converting PNG/JPG images to SVG, right in your browser. It combines the power of two best-in-class vectorization engines:

- **VTracer (WASM)** for color and advanced vectorization
- **Potrace (WASM, via [esm-potrace-wasm](https://github.com/tomayac/esm-potrace-wasm))** for crisp, high-quality black & white (B/W) tracing

All processing is fully client-side, making it perfect for static hosting (e.g., Vercel, Netlify) and privacy-focused applications. The library is ESM-first and works out-of-the-box in modern browsers and frameworks (React, Next.js, Vite, etc.).

---

## Features

- ⚡️ **High-performance**: Powered by Rust+WASM and C/WASM, runs fully client-side
- 🎨 **Color & B/W support**: Automatically selects the best engine for your needs
- 🛠️ **Customizable**: Fine-tune vectorization with VTracer and Potrace options
- ☁️ **Vercel/static hosting ready**: No backend or server required
- 🧩 **Easy integration**: Use in any TypeScript/JavaScript project (ESM only)
- 🔒 **Privacy-first**: Images never leave the browser
- 🧪 **Unified API**: One function, two engines, zero hassle

---

## How It Works

- **Color images**: Uses VTracer for advanced, multi-color SVG vectorization
- **Black & White images**: Uses Potrace (via esm-potrace-wasm) for optimal B/W tracing
- **Unified API**: You choose the mode with a simple option; the library handles the rest

---

## Installation

From npm:
```sh
npm install svgit4me
```

---

## Quick Start (Browser ESM)

### 1. Place VTracer WASM/JS Files
- Copy the following files from `node_modules/svgit4me/wasm/` to your public/static directory:
  - `vtracer_webapp.js`
  - `vtracer_webapp_bg.wasm`
  - `vtracer_webapp.d.ts` (optional, for TypeScript)
- For most setups, place them in your project's `public/` folder (e.g., `public/vtracer_webapp_bg.wasm`).

### 2. Import and Use
```js
import { convertToSVG } from 'svgit4me';

// For color SVG (VTracer)
const svgColor = await convertToSVG(file, { color: true });

// For black & white SVG (Potrace)
const svgBW = await convertToSVG(file, { color: false });
```

### 3. Customizing WASM Path (for Vercel/Next.js/static hosting)
```js
const svg = await convertToSVG(file, {
  color: true, // or false
  wasmPath: '/vtracer_webapp_bg.wasm' // Path relative to your public/static folder
});
```

---

## Detailed Usage & API

### `convertToSVG(image, options?): Promise<string>`
- `image`: `File`, `Blob`, or `ArrayBuffer` (e.g., from a file input, drag-and-drop, or fetch)
- `options`: See below
- **Returns:** SVG as a string

#### Example: File Input Handler
```js
fileInput.addEventListener('change', async (e) => {
  const file = e.target.files[0];
  // Use color or B/W based on your UI or user choice
  const svg = await convertToSVG(file, { color: false }); // Potrace for B/W
  // or
  // const svg = await convertToSVG(file, { color: true }); // VTracer for color
  // Do something with the SVG string (e.g., display or download)
});
```

#### Example: React Component
```jsx
import { useState } from 'react';
import { convertToSVG } from 'svgit4me';

function SvgUploader() {
  const [svg, setSvg] = useState('');
  return (
    <div>
      <input type="file" accept="image/*" onChange={async e => {
        const file = e.target.files[0];
        if (file) {
          const svgString = await convertToSVG(file, { color: true });
          setSvg(svgString);
        }
      }} />
      <div dangerouslySetInnerHTML={{ __html: svg }} />
    </div>
  );
}
```

---

## Options

| Option           | Type    | Default   | Engine    | Description                                      |
|------------------|---------|-----------|-----------|--------------------------------------------------|
| `color`          | boolean | true      | Both      | `true` for color (VTracer), `false` for B/W (Potrace) |
| `color_mode`     | string  | 'color'   | Both      | Alternative: 'color' or 'bw'                     |
| `wasmPath`       | string  |           | VTracer   | Custom path to `vtracer_webapp_bg.wasm`          |
| `potraceOptions` | object  |           | Potrace   | Options for Potrace (see below)                  |
| VTracer options  | various |           | VTracer   | See [VTracer WASM options](wasm/vtracer_webapp.d.ts) |
| ...              | ...     | ...       | ...       | See [esm-potrace-wasm options](https://github.com/tomayac/esm-potrace-wasm#api) |

### Potrace Options
- Any options supported by [esm-potrace-wasm](https://github.com/tomayac/esm-potrace-wasm#api) can be passed via `potraceOptions`.
- Example:
  ```js
  const svg = await convertToSVG(file, {
    color: false,
    potraceOptions: {
      turdsize: 100,
      optcurve: true,
      alphamax: 1.0
    }
  });
  ```

### VTracer Options
- See [wasm/vtracer_webapp.d.ts](wasm/vtracer_webapp.d.ts) for all available options.
- Common options:
  - `mode`: 'pixel' | 'polygon' | 'spline'
  - `color_precision`: number
  - `corner_threshold`: number
  - `filter_speckle`: number
  - `gradient_step`: number
  - `hierarchical`: 'stacked' | 'cutout'

---

## WASM File Handling & Static Hosting

- **VTracer**: You must serve `vtracer_webapp_bg.wasm` and `vtracer_webapp.js` from your public/static directory. Use the `wasmPath` option if your path is non-standard.
- **Potrace**: `esm-potrace-wasm` handles its own WASM loading. No manual copying required.
- **Next.js/Vercel**: Place WASM files in `/public` and use `/vtracer_webapp_bg.wasm` as the path.
- **Vite/React**: Use the default or specify the path as above.

---

## Troubleshooting

- **404 on vtracer_webapp_bg.wasm**: Ensure the file is in your public/static directory and the path matches `wasmPath` if set.
- **CORS errors**: Serve your app with a local server (not `file://`). Use `npx serve public` or similar.
- **TypeScript errors for esm-potrace-wasm**: The library includes a type shim. If you see type errors, ensure your `tsconfig.json` uses `moduleResolution: "bundler"` or add a local `src/esm-potrace-wasm.d.ts` file as shown in the repo.
- **Node.js support**: This library is browser-first. Node.js WASM support is not guaranteed.

---

## File Structure

- `wasm/` contains the VTracer WASM, JS, and type files.
- `src/SVGit4Me.ts` is the main TypeScript wrapper.
- `src/esm-potrace-wasm.d.ts` is a type shim for esm-potrace-wasm.

---

## Build & Publish

```sh
npm run build
npm publish --access public
```

---

## Contributing

Pull requests, issues, and feature requests are welcome!  
Please open an issue or PR on GitHub.

---

## License

MIT

---

## Acknowledgements

- Powered by [VTracer](https://github.com/visioncortex/vtracer) (MIT License)
- Powered by [esm-potrace-wasm](https://github.com/tomayac/esm-potrace-wasm) (LGPL License)
- Thanks to the Vision Cortex and Potrace teams for their amazing work!

---

## Next.js Compatibility

**If you are using SVGit4Me in a Next.js app:**

- Next.js does not allow direct ESM imports from the `public/` directory, and static assets are not automatically executed in the global scope.
- The VTracer glue code (`vtracer_webapp.js`) must be loaded globally so its exports are available on `window`.

**How to do this:**

1. Place `vtracer_webapp.js` and `vtracer_webapp_bg.wasm` in your `/public` directory.
2. In your custom `_app.tsx` (or `app/layout.tsx` for Next.js 13+), add:

```tsx
import Script from 'next/script';

export default function App({ Component, pageProps }) {
  return (
    <>
      <Script src="/vtracer_webapp.js" strategy="beforeInteractive" />
      <Component {...pageProps} />
    </>
  );
}
```

- This ensures `ColorImageConverter` and the glue code are available on `window` before your app runs.
- The SVGit4Me library will automatically use the global version if available, or fall back to dynamic import for other environments.

--- 