Home
Softono

Photeryx

Open source Apache-2.0 Rust
14
Stars
2
Forks
0
Issues
0
Watchers
9 months
Last Commit

 About Photeryx

A fast Rust + WebAssembly image processing pipeline for the browser, focused on preparing images before upload and display.

Platforms

Web Self-hosted

Languages

Rust

Links

Need Help Installing Photeryx?

We provide expert installation service for this software. Our team will install, configure, and secure Photeryx on your server. plans start at just $30.

Photeryx

High-performance Rust + WebAssembly image processing for modern web applications.

Photeryx logo

npm version npm downloads license GitHub issues Node version WebAssembly


🚀 Overview

Photeryx is a fast, lightweight image processing pipeline powered by Rust + WebAssembly, designed for browsers and modern frontend apps. It supports loading multiple images, transforming them, and exporting them in various formats, all locally without backend services.

This makes it ideal for:

  • Image editors
  • Upload preprocessors
  • Offline-first web apps
  • High-performance React / Vue / Svelte applications

✨ Core Features

  • Written in Rust, compiled to WebAssembly
  • Manage multiple images in memory at once
  • Load images from:
    • File
    • URL
    • ArrayBuffer
  • Transformations:
    • Rotate
    • Crop
    • Resize
    • Filters (brightness, contrast, blur, sharpen, etc.)
  • Export formats:
    • JPEG
    • PNG
    • WebP
  • Export as:
    • Uint8Array
    • Blob
    • Base64 data: URL
  • Duplicate detection across loaded images (returns Photo[][])
  • Manual memory control: free images when you’re done
  • Zero network dependency

📦 Installation

npm install photeryx

🧱 TypeScript API Overview

export interface RotationConfig {
  degrees: number;
}

export interface CropConfig {
  x: number;
  y: number;
  width: number;
  height: number;
}

export interface ResizeConfig {
  max_width: number;
  max_height: number;
  mode: "fit" | "exact" | "fill";
}

export interface SharpenConfig {
  radius: number;
  threshold: number;
}

export interface FilterConfig {
  grayscale?: boolean;
  invert?: boolean;
  sharpen?: SharpenConfig | null;
  brightness?: number | null;
  contrast?: number | null;
  blur?: number | null;
}

export type ExportConfig =
  | {
      format: "jpeg";
      quality: number;
    }
  | {
      format: "png";
    }
  | {
      format: "webp";
    };

export interface ImageConfig {
  rotation?: RotationConfig | null;
  crop?: CropConfig | null;
  resize?: ResizeConfig | null;
  filters?: FilterConfig | null;
  export: ExportConfig;
}

export declare class Photo {
  #private;
  constructor(manager: Photeryx, id: number);
  get id(): number;
  exportAsBytes(config: ImageConfig): Promise<Uint8Array>;
  exportAsBlob(config: ImageConfig): Promise<Blob>;
  exportAsDataUrl(config: ImageConfig): Promise<string>;
  free(): void;
  _unsafeFreeWithoutDetach(): void;
}

export declare class Photeryx {
  #private;
  get photos(): readonly Photo[];
  addFromFile(file: File): Promise<Photo>;
  addFromUrl(url: string): Promise<Photo>;
  addFromArrayBuffer(buffer: ArrayBuffer): Promise<Photo>;
  exportAllAsBytes(config: ImageConfig): Promise<Uint8Array[]>;
  exportAllAsBlobs(config: ImageConfig): Promise<Blob[]>;
  exportAllAsDataUrls(config: ImageConfig): Promise<string[]>;
  findDuplicates(threshold?: number): Promise<Photo[][]>;
  freeAll(): void;
  _detach(photo: Photo): void;
}

export default Photeryx;

🖼 Using Photeryx

1) Import & Initialize

import Photeryx, { type ImageConfig } from "photeryx";

const ph = new Photeryx();

2) Load Images

const photo1 = await ph.addFromFile(fileInput.files[0]);
const photo2 = await ph.addFromUrl("https://example.com/image.jpg");

// Or from ArrayBuffer
const buffer = await someFetchOrFileApi();
const photo3 = await ph.addFromArrayBuffer(buffer);

3) Configure Processing

const config: ImageConfig = {
  rotation: { degrees: 90 },
  crop: { x: 0, y: 0, width: 800, height: 600 },
  resize: { max_width: 1200, max_height: 1200, mode: "fit" },
  filters: {
    grayscale: false,
    sharpen: { radius: 2, threshold: 1 },
    brightness: 10,
    contrast: 20,
    blur: 1,
  },
  export: { format: "jpeg", quality: 85 },
};

4) Export Options (single image)

// Uint8Array
const bytes = await photo1.exportAsBytes(config);

// Blob
const blob = await photo1.exportAsBlob(config);

// Base64 string (data URL)
const base64 = await photo1.exportAsDataUrl(config);

// If you need a File instance:
const file = new File([blob], "output.jpeg", { type: "image/jpeg" });

5) Export All Loaded Images

// As Uint8Array[]
const allBytes = await ph.exportAllAsBytes(config);

// As Blob[]
const allBlobs = await ph.exportAllAsBlobs(config);

// As data URLs
const allDataUrls = await ph.exportAllAsDataUrls(config);

6) Duplicate Detection

findDuplicates compares all loaded photos and returns groups of Photo instances that are considered duplicates or very similar.

// Optionally pass a threshold (implementation-defined, e.g. 0–100)
const groups = await ph.findDuplicates(90);

// Example shape:
// [
//   [Photo, Photo],       // first duplicate group
//   [Photo, Photo, Photo] // second duplicate group
// ]

for (const group of groups) {
  console.log("Duplicate group:");
  for (const photo of group) {
    console.log("  Photo id:", photo.id);
  }
}

You can still access the flat list of currently loaded photos through ph.photos.

7) Memory Management

Photeryx gives you full control over WebAssembly memory:

photo1.free(); // Free one image
ph.freeAll(); // Free all images

⚠️ After .free() or .freeAll(), freed objects can no longer be used.


🧪 Browser Requirements

Feature Support
WebAssembly Required
ES6 Modules Required
Offscreen Canvas (optional) Optional

📚 Full API Reference

Class: Photeryx

Member / Method Description
photos: readonly Photo[] Readonly list of currently loaded photos
addFromFile(file) Load an image from a File
addFromUrl(url) Fetch and load image from a URL
addFromArrayBuffer(buffer) Load image from raw ArrayBuffer
exportAllAsBytes(config) Export all loaded images as Uint8Array[]
exportAllAsBlobs(config) Export all loaded images as Blob[]
exportAllAsDataUrls(config) Export all loaded images as Base64 data URLs (string[])
findDuplicates(threshold?) Find duplicate/similar images, returns groups of Photo[][]
freeAll() Free all images from WebAssembly memory

Class: Photo

Member / Method Description
id: number Stable numeric ID for this photo
exportAsBytes(config) Export as Uint8Array
exportAsBlob(config) Export as Blob
exportAsDataUrl(config) Export as Base64 data URL string
free() Free memory of this image

📄 License

Apache-2.0 © Mehran Taslimi


🔗 Repository

https://github.com/mehranTaslimi/photeryx