npm package: @patrickisgreat/string-art-engine
Description: Framework-agnostic string art generation engine using WebAssembly
Author: StringRing
Latest version: 1.0.0

# String Art Engine

A high-performance, framework-agnostic string art generation engine powered by WebAssembly and Rust. Transform any image into beautiful string art with advanced algorithms and customizable parameters.

## Features

- **High Performance**: WebAssembly-powered Rust algorithms for fast processing
- **Framework Agnostic**: Works with React, Vue, Angular, vanilla JS, or any TypeScript/JavaScript project
- **Highly Configurable**: Extensive parameters for fine-tuning results
- **Advanced Algorithms**: Smart preprocessing, quality analysis, and optimization
- **Parallel Processing**: Multi-threaded processing for complex images
- **Precise Control**: Line count optimization and thread thickness simulation
- **Quality Analysis**: Automatic image suitability assessment

## Installation

```bash
npm install string-art-engine
```

## Quick Start

```typescript
import { StringArtEngine } from 'string-art-engine';

// Create engine instance
const engine = new StringArtEngine({
  pinCount: 200,
  maxLineCount: 4000,
  lineWeight: 0.25
});

// Process an image
async function generateStringArt(imageData: ImageData) {
  const result = await engine.processImage(imageData);
  
  console.log(`Generated ${result.lineCount} lines`);
  console.log('Pin coordinates:', result.pinCoordinates);
  console.log('Line sequence:', result.lineSequence);
  
  return result;
}
```

## Advanced Usage

### Custom Configuration

```typescript
import { StringArtEngine, DEFAULT_CONFIG } from 'string-art-engine';

const engine = new StringArtEngine({
  ...DEFAULT_CONFIG,
  pinCount: 300,           // More pins = finer detail
  maxLineCount: 6000,      // More lines = more detail
  lightnessPenalty: 0.8,   // Higher = more emphasis on dark areas
  qualityMode: 'enhanced', // Better quality at cost of speed
  useParallelProcessing: true // Use multiple threads
}, {
  enableLogging: true,     // Enable console logging
  useWorker: true,         // Use web worker (recommended)
  onProgress: (progress) => {
    console.log(`${progress.stage}: ${progress.progress}%`);
  }
});
```

### Image Quality Analysis

```typescript
// Analyze image before processing
const analysis = await engine.getQualityAnalysis(imageData);
console.log(`Quality Score: ${(analysis.score * 100).toFixed(1)}%`);
console.log(`Recommendation: ${analysis.recommendation}`);

// Preprocess low-quality images
if (analysis.score < 0.5) {
  const preprocessed = await engine.preprocessImage(imageData);
  if (preprocessed) {
    imageData = preprocessed;
  }
}
```

### Line Count Optimization

```typescript
// Generate with specific line count
const result = await engine.recalculateWithLineCount(imageData, 3000);

// Update configuration dynamically
engine.updateConfig({
  lineWeight: 0.3,
  lightnessPenalty: 0.9
});
```

## API Reference

### StringArtEngine

#### Constructor
```typescript
constructor(config?: Partial<StringArtConfig>, options?: StringArtEngineOptions)
```

#### Methods

##### `processImage(imageData: ImageData): Promise<StringArtResult>`
Process an image to generate string art.

##### `recalculateWithLineCount(imageData: ImageData, targetLines: number): Promise<StringArtResult>`
Generate string art with a specific target line count.

##### `analyzeImageQuality(imageData: ImageData): Promise<number>`
Analyze image quality (returns 0-1 score).

##### `getQualityAnalysis(imageData: ImageData): Promise<ImageQualityAnalysis>`
Get detailed quality analysis with recommendations.

##### `preprocessImage(imageData: ImageData): Promise<ImageData | null>`
Preprocess image for better string art quality.

##### `updateConfig(config: Partial<StringArtConfig>): void`
Update engine configuration.

##### `destroy(): void`
Clean up resources.

### Configuration Options

```typescript
interface StringArtConfig {
  pinCount: number;              // Number of pins (50-500)
  imageSize: number;             // Image size in pixels
  minDistance: number;           // Min distance between pins
  maxLineCount: number;          // Maximum lines to generate
  lineWeight: number;            // Line opacity (0-1)
  lightnessPenalty: number;      // Dark area emphasis (0-1)
  lineNorm: number;              // Penalty calculation method
  useImportanceWeighting: boolean; // Use importance maps
  qualityMode: 'standard' | 'enhanced' | 'multipass' | 'parallel';
  useParallelProcessing: boolean; // Enable multithreading
  numThreads?: number;           // Number of threads
}
```

### Result Structure

```typescript
interface StringArtResult {
  lineSequence: number[];        // Pin sequence for drawing
  pinCoordinates: [number, number][]; // Pin positions
  processingTime: number;        // Time taken (ms)
  lineCount: number;             // Actual lines generated
  qualityScore?: number;         // Input quality score
}
```

## Examples

### React Component

```tsx
import React, { useState, useRef } from 'react';
import { StringArtEngine } from 'string-art-engine';

function StringArtGenerator() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);
  const engineRef = useRef(new StringArtEngine());

  const handleImageUpload = async (event) => {
    const file = event.target.files[0];
    if (!file) return;

    setLoading(true);
    
    // Convert file to ImageData
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const img = new Image();
    
    img.onload = async () => {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);
      
      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      const stringArtResult = await engineRef.current.processImage(imageData);
      
      setResult(stringArtResult);
      setLoading(false);
    };
    
    img.src = URL.createObjectURL(file);
  };

  return (
    <div>
      <input type="file" accept="image/*" onChange={handleImageUpload} />
      {loading && <p>Generating string art...</p>}
      {result && (
        <div>
          <p>Generated {result.lineCount} lines in {result.processingTime.toFixed(0)}ms</p>
          {/* Render string art using result.lineSequence and result.pinCoordinates */}
        </div>
      )}
    </div>
  );
}
```

### Canvas Rendering

```typescript
function renderStringArt(canvas: HTMLCanvasElement, result: StringArtResult) {
  const ctx = canvas.getContext('2d');
  const { lineSequence, pinCoordinates } = result;
  
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // Set line style
  ctx.strokeStyle = 'rgba(0, 0, 0, 0.1)';
  ctx.lineWidth = 0.5;
  
  // Draw lines
  for (let i = 0; i < lineSequence.length - 1; i++) {
    const fromPin = lineSequence[i];
    const toPin = lineSequence[i + 1];
    const from = pinCoordinates[fromPin];
    const to = pinCoordinates[toPin];
    
    ctx.beginPath();
    ctx.moveTo(from[0], from[1]);
    ctx.lineTo(to[0], to[1]);
    ctx.stroke();
  }
}
```

## Building from Source

```bash
# Install dependencies
npm install

# Build WASM module
npm run build:wasm

# Build TypeScript
npm run build:ts

# Build everything
npm run build
```

## Requirements

- Node.js 16+
- Modern browser with WebAssembly support
- For building: Rust toolchain with `wasm-pack`

## Performance Tips

1. **Use Web Workers**: Enable `useWorker: true` for non-blocking processing
2. **Optimize Pin Count**: Start with 200 pins, increase for more detail
3. **Quality vs Speed**: Use 'standard' mode for speed, 'enhanced' for quality
4. **Parallel Processing**: Enable for complex images with many pins
5. **Image Preprocessing**: Use `preprocessImage()` for low-quality inputs

## Browser Support

- Chrome 57+
- Firefox 52+
- Safari 11+
- Edge 16+

## License

MIT

## Contributing

Contributions welcome! Please read our contributing guidelines and submit pull requests to our repository.

## Credits

Built with ❤️ by the StringRing team. Powered by Rust, WebAssembly, and modern web technologies.