Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deskew (Node.js Port)

A pure JavaScript / Node.js port of Stéphane Brunner's sbrunner/deskew library. It calculates the skew angle of a text-containing image and provides functionality to rotate and align it.

This implementation has zero external native/binary dependencies, meaning it will run anywhere Node.js runs without needing a compiler, Python, or external image utilities.


Features

  • Pure JavaScript: Built-in Canny edge detector, bilinear Non-Maximum Suppression, and Hough Line Transform.
  • Accurate: Passes all 8 official deskew test cases with 100% precision.
  • Self-Contained: The core library accepts raw pixel data, making it compatible with any image library (pngjs, jimp, sharp, HTML5 Canvas, etc.).
  • CLI Tool Included: Rotate and save corrected images directly from your terminal.

Installation

npm install @flueschpluesch/deskew

CLI Usage

Get the skew angle of an image:

npx @flueschpluesch/deskew input.png

Correct (rotate) and save an image:

npx @flueschpluesch/deskew --output output.png input.png

Options:

  • -o, --output <path>: Path to save the rotated output image.
  • --sigma <val>: Blur strength (Gaussian sigma). Default is 3.0.
  • --num-peaks <val>: Number of peaks to detect in Hough space. Default is 20.
  • --num-angles <val>: The number of angles to evaluate. Default is 180.
  • --background <val>: Background fill color for empty corners. Single value for grayscale (e.g. 255) or comma-separated values (e.g. 255,255,255).

Library Usage

The library can be used with any package that provides raw pixel data. Here is an example using pngjs:

const fs = require('fs');
const { PNG } = require('pngjs');
const { determineSkew, rotate } = require('@flueschpluesch/deskew');

// 1. Load an image
fs.createReadStream('input.png')
  .pipe(new PNG())
  .on('parsed', function () {
    // 2. Determine the skew angle in degrees
    const angle = determineSkew({
      width: this.width,
      height: this.height,
      data: this.data // Uint8Array of RGBA values
    });
    
    console.log(`Skew angle detected: ${angle} degrees`);

    if (angle !== null) {
      // 3. Rotate the image to correct the skew
      const rotated = rotate(
        { width: this.width, height: this.height, data: this.data },
        angle,
        { resize: true, background: [255, 255, 255, 255] } // White background fill
      );

      // 4. Save the corrected image
      const outPng = new PNG({ width: rotated.width, height: rotated.height });
      outPng.data = Buffer.from(rotated.data);
      
      outPng.pack().pipe(fs.createWriteStream('output.png'));
    }
  });

API

determineSkew(image, options)

Calculates the skew angle in degrees of an image.

  • image: An object containing { width: number, height: number, data: Uint8Array | Buffer }.
    • Supports RGBA (width * height * 4 bytes), RGB (width * height * 3 bytes), or Grayscale (width * height bytes) data.
  • options:
    • sigma (number, default: 3.0): Standard deviation of the Gaussian filter.
    • numPeaks (number, default: 20): Number of peaks to detect in Hough space.
    • anglePm90 (boolean, default: false): If true, returns angles in range [-90, 90] degrees; otherwise returns angles in range [-45, 45] degrees.
    • minAngle (number): Minimum angle in degrees to consider.
    • maxAngle (number): Maximum angle in degrees to consider.
    • minDeviation (number, default: 1.0): Minimum deviation between angles in degrees.
    • numAngles (number): Optional backward-compatible way to specify resolution (forces minDeviation = 180 / numAngles).

Returns: The skew angle in degrees (float), or null if no skew could be determined.

rotate(image, angleDegrees, options)

Rotates the image by a given angle around its center.

  • image: { width, height, data } object.
  • angleDegrees: Angle to rotate by in degrees. Positive rotates counter-clockwise.
  • options:
    • resize (boolean, default: true): Adjusts the output dimensions to fit the rotated image.
    • background (number | number[], default: [0, 0, 0, 0]): Color used to fill the empty corners created by rotation.

Returns: A new { width, height, data } object.


License

This project is licensed under the MIT License.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages