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 🙏

© 2025 – Pkg Stats / Ryan Hefner

alogos

v1.0.0

Published

A lightweight library for detecting synthetic images using luminance-gradient PCA analysis

Readme

Alogos

A lightweight JavaScript library for detecting synthetic images using luminance-gradient PCA analysis

NPM Version License TypeScript

Overview

Alogos provides a simple yet effective way to distinguish between real photographs and AI-generated (diffusion model) images by analysing their gradient fields.

Real images produce coherent gradient fields tied to physical lighting and sensor characteristics, while diffusion-generated images show unstable high-frequency structures from the denoising process. By converting RGB to luminance, computing spatial gradients, and evaluating the covariance through PCA, the difference becomes visible in a single projection.

This provides a lightweight and interpretable way to assess image authenticity without relying on metadata or complex classifier models.

ELI5: Light in the real world behaves in smooth and predictable ways, cameras capture light using sensors that known and consistent patterns. This creates smooth and coherent gradients (changes to light to dark). But AI generated images using diffusion models, generate images by repeatedly removing noise, this process creates tiny unstable high-frequency wiggles in the brightness patterns. These are not obvious to the human eye, but these show up in gradient data.

Features

  • Simple API - Easy to use with sensible defaults
  • Scientific Approach - Based on gradient field analysis and PCA
  • Lightweight - No heavy dependencies
  • Fast - Efficient algorithms suitable for real-time analysis
  • Interpretable - Provides detailed metrics and confidence scores
  • Configurable - Customisable thresholds and parameters
  • TypeScript - Full type definitions included
  • Well-tested - Comprehensive test coverage

Installation

npm install alogos

Or with yarn:

yarn add alogos

Quick Start

import { detectSyntheticImage } from 'alogos';

// Assume you have image data in RGBA format
const imageData = {
  width: 800,
  height: 600,
  data: new Uint8ClampedArray(800 * 600 * 4), // RGBA pixel data
};

// Analyse the image
const result = detectSyntheticImage(imageData);

console.log(`Is synthetic: ${result.isSynthetic}`);
console.log(`Confidence: ${result.confidence.toFixed(2)}`);
console.log(`Raw score: ${result.rawScore.toFixed(3)}`);

Usage

Basic Usage

import { SyntheticImageDetector } from 'alogos';

// Create a detector instance
const detector = new SyntheticImageDetector();

// Analyse an image
const result = detector.analyse(imageData);

if (result.isSynthetic) {
  console.log(`This image is likely synthetic (confidence: ${result.confidence})`);
} else {
  console.log(`This image is likely real (confidence: ${result.confidence})`);
}

With Custom Options

import { SyntheticImageDetector } from 'alogos';

const detector = new SyntheticImageDetector({
  threshold: 0.7,           // Custom detection threshold (0-1)
  numComponents: 10,        // More principal components for analysis
  normaliseGradients: true, // Normalise gradient values
  minImageSize: 128,        // Minimum image dimension
});

const result = detector.analyse(imageData);

Getting Image Data from Canvas

// In a browser environment
const canvas = document.getElementById('myCanvas') as HTMLCanvasElement;
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

const result = detectSyntheticImage(imageData);

Getting Image Data from File (Node.js)

You'll need a library like canvas or sharp to read images in Node.js:

import { createCanvas, loadImage } from 'canvas';
import { detectSyntheticImage } from 'alogos';

async function analyseImageFile(imagePath: string) {
  const image = await loadImage(imagePath);
  const canvas = createCanvas(image.width, image.height);
  const ctx = canvas.getContext('2d');
  
  ctx.drawImage(image, 0, 0);
  const imageData = ctx.getImageData(0, 0, image.width, image.height);
  
  return detectSyntheticImage(imageData);
}

// Usage
const result = await analyseImageFile('./photo.jpg');
console.log(result);

Advanced: Gradient Field Analysis

import { SyntheticImageDetector } from 'alogos';

const detector = new SyntheticImageDetector();

// Get detailed gradient information
const gradientField = detector.analyseGradients(imageData);

console.log('Gradient dimensions:', gradientField.width, 'x', gradientField.height);
console.log('X-gradient at (10, 10):', gradientField.gx[10][10]);
console.log('Y-gradient at (10, 10):', gradientField.gy[10][10]);

Advanced: Using Low-Level APIs

import {
  imageToluminanceMatrix,
  computeGradients,
  flattenGradientField,
  performPCA,
  computePCAScore,
} from 'alogos';

// Step-by-step analysis
const luminance = imageToluminanceMatrix(imageData);
const gradients = computeGradients(luminance);
const gradientMatrix = flattenGradientField(gradients);
const pcaResult = performPCA(gradientMatrix, 5);
const score = computePCAScore(pcaResult);

console.log('Detection score:', score);
console.log('Primary variance:', pcaResult.explainedVariance[0]);

API Reference

Main Classes

SyntheticImageDetector

The main detector class.

Constructor:

new SyntheticImageDetector(options?: DetectorOptions)

Methods:

  • analyse(imageData: ImageData): DetectionResult - Analyses an image
  • analyseGradients(imageData: ImageData): GradientField - Returns gradient field
  • setOptions(options: Partial<DetectorOptions>): void - Updates options
  • getOptions(): Required<DetectorOptions> - Gets current options

Functions

detectSyntheticImage(imageData, options?)

Convenience function to analyse a single image with default options.

Types

ImageData

interface ImageData {
  width: number;
  height: number;
  data: Uint8ClampedArray | number[];
}

DetectionResult

interface DetectionResult {
  isSynthetic: boolean;
  confidence: number;
  rawScore: number;
  metadata: {
    pixelsAnalysed: number;
    primaryVariance: number;
    coherence: number;
  };
}

DetectorOptions

interface DetectorOptions {
  threshold?: number;                      // Default: 0.5
  numComponents?: number;                  // Default: 5
  normaliseGradients?: boolean;            // Default: true
  minImageSize?: number;                   // Default: 64
  filterCompressionArtifacts?: boolean;    // Default: true
}

GradientField

interface GradientField {
  gx: number[][];
  gy: number[][];
  width: number;
  height: number;
}

How It Works

Alogos uses a multi-step process to analyse images:

  1. RGB to Luminance Conversion: Converts colour images to greyscale using the standard photometric formula: L = 0.2126 × R + 0.7152 × G + 0.0722 × B

  2. Gradient Computation: Calculates spatial gradients using central differences:

    • Gx(x,y) = [L(x+1,y) - L(x-1,y)] / 2
    • Gy(x,y) = [L(x,y+1) - L(x,y-1)] / 2
  3. Matrix Formation: Flattens the gradient field into an N×2 matrix where N is the number of pixels

  4. Covariance Analysis: Computes the covariance matrix: C = (1/N) × M^T × M

  5. PCA Decomposition: Performs eigendecomposition to find principal components

  6. Score Computation: Analyses variance distribution and projection statistics to determine likelihood of synthesis

Real photographs tend to show:

  • Higher coherence in gradient fields
  • More concentrated variance in primary components
  • Gaussian-like projection distributions

Synthetic images tend to show:

  • Unstable high-frequency gradient structures
  • More dispersed variance across components
  • Heavy-tailed projection distributions (higher kurtosis)

Performance

Typical performance on a modern CPU:

  • Small images (256×256): ~10-20ms
  • Medium images (512×512): ~40-80ms
  • Large images (1024×1024): ~150-300ms

Performance scales roughly with O(n) where n is the number of pixels.

Limitations

  • Requires images to be at least 64×64 pixels
  • Works best on images with natural content
  • May produce false positives on heavily processed or filtered real images
  • Detection accuracy depends on the quality and type of synthetic generation model
  • Not foolproof - should be used as one signal among many for authenticity verification

Important Considerations

JPEG Compression Artifacts: A significant consideration in synthetic image detection is that real photographs are often JPEG compressed, while synthetic images may be saved as PNG or with minimal compression. This compression difference can create detectable patterns. As noted in research like the "JPEG or Fake" paper, some detection methods inadvertently learn to detect JPEG compression artifacts rather than true synthetic features.

Mitigation in Alogos: By default, Alogos applies a high-pass filter (filterCompressionArtifacts: true) to reduce the impact of JPEG block artifacts and focus on high-frequency patterns characteristic of diffusion models. This can be disabled if needed:

const detector = new SyntheticImageDetector({
  filterCompressionArtifacts: false  // Disable if analysing uncompressed images
});

Best Practices:

  • The default settings are optimised for mixed compression scenarios
  • For research or validation, test with consistent compression across all images
  • Be aware that detection is probabilistic - use as one signal among many
  • Consider the image source and processing history in your interpretation

Contributing

Contributions are welcome! Please open an issue or submit a Pull Request on GitHub.

Licence

MIT

Acknowledgements

This library implements the gradient field analysis technique for synthetic image detection discovered and documented by Kavishka Abeywardhana.

The approach was originally shared in this LinkedIn post, where Kavishka demonstrated that luminance-gradient PCA analysis reveals consistent separation between real photographs and diffusion-generated images.

All credit for the discovery and methodology goes to Kavishka Abeywardhana. This library is simply an implementation of his technique made available for the JavaScript/TypeScript ecosystem.

Further Reading

Support

If you find this library useful, please consider:

  • Starring the repository
  • Reporting bugs
  • Suggesting features
  • Improving documentation

Citation

If you use Alogos in academic work, please cite:

@software{alogos2025,
  title={Alogos: Synthetic Image Detection using Gradient Fields},
  author={Ellwood, Rhys},
  note={Implementation of technique by Kavishka Abeywardhana},
  year={2025},
  url={https://github.com/REllwood/alogos}
}

Please also cite the original technique:

@misc{abeywardhana2025gradient,
  title={Synthetic Image Detection using Gradient Fields},
  author={Abeywardhana, Kavishka},
  year={2025},
  url={https://www.linkedin.com/posts/kavishka-abeywardhana-01b891214_synthetic-image-detection-using-gradient-activity-7397874600769982465-TC0c}
}