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 🙏

© 2026 – Pkg Stats / Ryan Hefner

snap-photo

v0.0.6

Published

Slim Node.js image processing & compressing library 📸

Readme

Snap 📸

npm i snap-photo

Snap is a light weighted Node.js image processing wrapper library for generating web-friendly images using node-canvas.

Benefits of Using Node-Canvas

  • Compression: compress image locally by adjusting image quality
  • Operations: support every web-canvas magic, and more!
  • Web-friendly: generate images that save spaces/bandwidth and support browsers natively
  • Flexible: draw, write, reshape... it's a canvas!

Benefits of Using Snap

  • Support: easy to install; support popular platforms & image formats
  • Simple: simple code, simple operations
  • Local: make use of server-side power and local file structure
  • Batch: process mass images at once

Get Started

const snap = require('snap-photo')

snap.setRootDir('/Your/Folder/To/Image').createImage('1.png').then((image) => {
    // rotate image clockwise 90° and set width 100px, render canvas
    image.rotate(90).width(100).render()

    // regret what you did? revert to last state!
    image.revert()

    // image is 10% size than before
    image.scale(0.1).render()

    /** exportImage: 
     * {
     *     src: {
     *         src: '/Source/Folder',
     *         type: 'LOCAL',
     *         name: '1.png'
     *     },
     *     export: {
     *         dir: '/Export/Folder',
     *         quality: 0.1,
     *         name: 'photo.jpeg',
     *         format: 'JPEG',
     *         MD5HashName: false
     *     },
     *     name: 'photo.jpeg',
     *     info: {
     *         exif: {
     *             image: [Object],
     *             thumbnail: {},
     *             exif: [Object],
     *             gps: {},
     *             interoperability: {},
     *             makernote: {}
     *         },
     *         width: 1440,
     *         height: 1080
     *     }
     * }
     * */
    var exportImageName = image.export({
        dir: '/Export/Folder',
        quality: 0.1,
        name: 'photo',
        format: 'JPEG'
    })
})

Other Examples

Batch processing images, async style

async function processImages(images) {
    var images = await snap.createImages(images)

    var thread = snap.createThread(images).render((image, name, format) => {
        // render image in batch
        if(format === 'PNG') {
            return image.scale(0.1)
        }else if(format === 'JPEG') {
            return image.scale(10)
        }
    })
    
    /**
     * 
     *  exportImages: 
     *  [
     *      {
     *          src: {
     *              src: '/Source/Folder',
     *              type: 'LOCAL',
     *              name: '1.png'
     *          },
     *          export: {
     *              dir: '/Export/Folder',
     *              quality: 0.1,
     *              name: '91ba97271e9fdb149db252c8f00772b1.jpeg',
     *              format: 'JPEG',
     *              MD5HashName: false
     *          },
     *          name: '91ba97271e9fdb149db252c8f00772b1.jpeg',
     *          info: {
     *              exif: {
     *                  image: [Object],
     *                  thumbnail: {},
     *                  exif: [Object],
     *                  gps: {},
     *                  interoperability: {},
     *                  makernote: {}
     *              },
     *              width: 1440,
     *              height: 1080
     *          }
     *      },
     *      ...
     *  ]
     **/
    var exportDir = '/Export/Folder'
    var exportImages = thread.export({
        dir: exportDir,
        prefix: 'snap_',
        quality: 0.1,
        naming: 'MD5Hash', // increment, MD5Hash. original
        format: 'JPEG'  // JPEG, PNG, PDF
    })
}

processImages(['m.jpg', 'n.png'])

Render raw canvas

image.renderRaw((canvas) => {
    var ctx = canvas.getContext('2d')
    // ...some canvas operations
    return canvas
})

API

Snap is composite of two elements:

  • SnapImage: a canvas instance of a single image
  • SnapThread: a batch processing thread that takes Array<SnapImage> as input and render them in batch with the same operations

Snap

Snap.setRootDir(path)

Set the global root file directory for Snap to work on

Snap.setRootDir('/Your/Folder/To/Image')

Parameters:

  • path(string): the root path

Returns:

  • Snap

Async Snap.createImage(fileName)

Create a SnapImage instance from an image If root directory is not set, default dir is your project dir

var image = await Snap.createImage('1.jpg')

Parameters:

  • fileName(string): the source image

Returns:

  • SnapImage

Async Snap.createImages(fileNames)

Create an Array of SnapImage from multiple images If root directory is not set, default dir is your project dir

var images = await Snap.createImages(['1.jpg', '2.png'])

Parameters:

  • fileName(Array<string>): source images

Returns:

  • Array<SnapImage>

Snap.createThread(images)

Create a processing thread from SnapImage

Snap.createThread(images)

Parameters:

  • images(Array<SnapImage> | SnapImage): SnapImage instances

Returns:

  • SnapThread

SnapImage

SnapImage.scale(num)

Scale a SnapImage both width and height new size = [width * num, height * num]

image.scale(10) // enlarge the image by x 10

Parameters:

  • num(number): Scaling factor

Returns:

  • SnapImage

SnapImage.width(num)/.height(num)

Set a SnapImage's width/height, in pixels

// number
image.width(200)
// function
image.height((originalH) => {
    return originalH / 100
})

Parameters:

  • num(number | function(originalW/H): New width/height)

Returns:

  • SnapImage

SnapImage.contextRotate(angel)

Rotate context inside a canvas, in degree angels

image.contextRotate(90)

Parameters:

  • angel(number)

Returns:

  • SnapImage

SnapImage.canvasRotate(angel)

Rotate the canvas in whole, in degree angels

image.canvasRotate(90)  // only supports 90, 180, 270

Parameters:

  • angel(number)

Returns:

  • SnapImage

SnapImage.flip(orientation)

Flip image along an orientation

image.flip('vertical')  // vertical, horizontal

Parameters:

  • orientation(number)

Returns:

  • SnapImage

SnapImage.x(x)

Move image from the left most long x

// number
image.x(10)

// function
image.x((originalW) => {
    return originalW / 100
})

Parameters:

  • x(number | function(originalW): New x)

Returns:

  • SnapImage

SnapImage.y(y)

Move image from the top most long y

// number
image.y(10)

// function
image.y((originalH) => {
    return originalH / 100
})

Parameters:

  • y(number | function(originalH): New y)

Returns:

  • SnapImage

SnapImage.render()

Render canvas after operations => save progress

image.render()

Returns:

  • SnapImage

SnapImage.renderRaw(func)

Render previous operations => render canvas directly => save progress

image.flip('vertical').renderRaw((canvas) => {
    // ...some canvas operations
    return canvas
})

Parameters:

  • func(function(canvas): canvas)

Returns:

  • SnapImage

SnapImage.revert()

Revert image to latest render

image.revert()

Returns:

  • SnapImage

SnapImage.export(options)

Export image

image.export({
    name: 'cat',    // default snap_originalName
    // or name image by its file hash
    MD5HashName: true,
    format: 'PNG', // PNG, JPEG, default JPEG
    quality: 0.1,   // between 0-1, default RAW
    dir: '/Export/Folder'   // default root dir
})

Parameters:

  • options(object): everything is optional; even passing in options is optional

Returns:

  • info:
object {
    src: {
        src: '/Source/Folder',
        type: string,
        name: string
    },
    export: {
        dir: '/Export/Folder',
        quality: number,
        name: string,
        format: string',
        MD5HashName: boolean
    },
    name: 'photo.jpeg',
    info: {
        exif: {
            image: [Object],
            thumbnail: {},
            exif: [Object],
            gps: {},
            interoperability: {},
            makernote: {}
        },
        width: number,
        height: number
    }
}

SnapThread

SnapThread.render(func)

Render SnapImage in batch

thread.render((image, name, format, src) => {
    // render image in batch
    return image
})

Parameters:

  • func(function(image: SnapImage, name: string, format: string, src: string): SnapImage) // name => original name; format => PNG or JPEG; src => Image/Original/Folder

Returns:

  • SnapThread

SnapThread.export(options)

Export images in batch

thread.export({
    dir: '/Export/Folder'   // default root dir
    prefix: 'snap_',    // default snap_
    quality: 0.1,   // between 0-1, default RAW
    naming: 'MD5Hash', // increment, MD5Hash, originalName, default originalName
    format: 'JPEG'  // JPEG, PNG, PDF
})

Parameters:

  • options(object): everything is optional; even passing in options is optional

Returns:

  • info:
Array<object> [{
    src: {
        src: '/Source/Folder',
        type: string,
        name: string
    },
    export: {
        dir: '/Export/Folder',
        quality: number,
        name: string,
        format: string',
        MD5HashName: boolean
    },
    name: 'photo.jpeg',
    info: {
        exif: {
            image: [Object],
            thumbnail: {},
            exif: [Object],
            gps: {},
            interoperability: {},
            makernote: {}
        },
        width: number,
        height: number
    }
}]

TODO

  • SnapImage.filter(): blur/filter
  • SnapImage.text(): add text (watermark)
  • SnapImage.overlay(): overlay two canvas (watermark)
  • SnapThread.concat(): thread concat
  • SnapImage.exportBuffer(): export to Buffer
  • SnapImage.init(): import PDF
  • SnapImage.info(): get Image information
  • Snap.setRootUrl(): support images from remote sites

Credit

Zimo Xiao Email: [email protected]