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 🙏

© 2024 – Pkg Stats / Ryan Hefner

analyze-image

v1.0.0

Published

Analyzes an image and detects potential improvements for a webpage

Downloads

5,019

Readme

analyze-image

Analyzes an image for improvements on a webpage

Deeply inspired by https://github.com/macbre/analyze-css

Promise example

const analyzeImage = require('analyze-image');
const browserData = {
    html: '<img srcset="image1.jpg 400w, image2.jpg 800w" sizes="50vw">'
    displayWidth: 300,
    displayHeight: 200,
    viewportWidth: 1200,
    viewportHeight: 800
};
const options = {
    // ...
};

const file = // An image file as a Buffer or a String (base64 encoded image or textual SVG image)
// Supported formats are jpg, png, webp, avif, gif, svg

analyzeImage(image, browserData, options)

    .then(function(result) {
        console.log("SUCESS:");
        console.log(result);
    })

    .catch(function(error) {
        console.log("ERROR:");
        console.log(error);
    });

Async/await example

const analyzeImage = require('analyze-image');
const browserData = {
    html: '<img src="image.jpg">'
    displayWidth: 300,
    displayHeight: 200
};
const options = {
    // ...
};
const file = // An image file as a Buffer or a String (base64 encoded image or textual SVG image)

try {
    const result = await analyzeImage(image, browserData, options);
    console.log("SUCESS:");
    console.log(result);

} catch(error) {
    console.log("ERROR:");
    console.log(error);
}


Browser data

| Data name | Type | Default | Description | | --------- | ---- | ------- | ----------- | | html | string | | html code for the img or picture element, can be retrived in JS with imageElement.outerHTML | | displayWidth | number | | number of "CSS pixels" the image is displayed on, can be retrieved in JS with imageElement.width | | displayHeight | number | | number of "CSS pixels" the image is displayed on, can be retrieved in jS with imageElement.height | | viewportWidth | number | | number of "CSS pixels" of the browser's window, can be retrieved in JS with window.innerWidth | | viewportHeight | number | | number of "CSS pixels" of the browser's window, can be retrieved in JS with window.innerHeight | | dpr | number | 1 | the browser's device pixel ratio, can be retrieved in JS with window.devicePixelRatio |

Options

| Option name | Type | Default | Description | | ----------- | ---- | ------- | ----------- | | jpegQuality | number | 85 | quality used for JPEG recompression, integer 1-100 | | pngQuality | number | 90 | quality used for PNG recompression, integer 1-100 | | webpQuality | number | 82 | quality used for WebP recompression, integer 1-100 | | avifQuality | number | 64 | quality used for AVIF recompression, integer 1-100 | | gifsicleLevel | number | 3 | level of GIF compression effort sent to Gifsicle (1 is average but fast, 2 is medium, 3 is efficient but slow) |

Result object

Result is an object with the following properties:

{
    // Contains various data extracted from the original image
    stats: {
        format: // [String] Name of the image format detected (`jpg`, `png`, `webp`, `avif`, `gif`, `svg`)
        mymeType: // [string] Official mime type of the image format (i.e. `image/jpeg`)
        fileSize: // [number] Number of bytes of the provided image
        width: // [number] Provided image's width in pixel
        height: // [number] Provided image's height in pixel
        displayRatio: // [number] Provided image's dimensions divided by the dimensions of the physical pixels the image is displayed on. The image is too large if > 1, too small if < 1
        displayDensity: // [number] Provided image's dimensions divided by the dimensions of the CSS pixels the image is displayed on. Basically, displayDensity = displayRatio x dpr
    },
    // Contains the various transformations tested on the image
    transforms: {
        // Property only available if the image was successfuly optimized
        optimized: {
            fileSize: // [number] Weight in bytes of the original file
            newFileSize: // [number] Weight in bytes after optimization
            body: // [buffer] Optimized file
        },
        // Property only available if resizing the image provides good results (requires `displayWidth` and `displayHeight` inputs)
        resized: {
            naturalWidth: // [number] Provided image's width in pixel
            naturalHeight: // [number] Provided image's height in pixel
            fileSize: // [number] Weight in bytes of the image before resizing. Using the optimized weight if available, because it makes no sense comparing rescaled+optimized vs unoptimized.
            newWidth: // [number] New file's width in pixel
            newHeight: // [number] New file's height in pixel
            dpr: // [numer] Screen density used to determine new dimensions
            newFileSize: // [number] Weight in bytes after resizing
            body: // [buffer] Resized file
        },
        // Property only available if converting the image to WebP provides good results
        webpEncoded: {
            currentFormat: // [string] Type of the original file
            fileSize: // [number] Weight in bytes of the original file
            newFileSize: // [number] Weight in bytes after conversion
            body: // [buffer] WebP file
        },
        // Property only available if converting the image to AVIF provides good results
        avifEncoded: {
            currentFormat: // [string] Type of the original file
            fileSize: // [number] Weight in bytes of the original file
            newFileSize: // [number] Weight in bytes after conversion
            body: // [buffer] AVIF file
        }
    },
    // Contains the various transformations tested on the image
    offenders: {
        // Appears only if the image could be significantly smaller with a better compression
        imageNotOptimized: {
            fileSize: // [number] Weight in bytes of the original file
            newFileSize: // [number] Weight in bytes after optimization
        },
        // Appears only if the image could be significantly smaller when resized to fit tis display dimensions
        imageScaledDown: {
            naturalWidth: // [number] Provided image's width in pixel
            naturalHeight: // [number] Provided image's height in pixel
            fileSize: // [number] Weight in bytes of the image before resizing. Using the optimized weight if available, because it makes no sense comparing rescaled+optimized vs unoptimized.
            newWidth: // [number] New file's width in pixel
            newHeight: // [number] New file's height in pixel
            dpr: // [numer] Screen density used to determine new dimensions
            newFileSize: // [number] Weight in bytes after resizing
        },
        // Appears only if the image density is >2.2 on a high density screen (>2.2 dpr)
        imageExcessiveDensity: {
            alreadyResized: // [boolean] If true, means that we are using the resized file as a reference, otherwise it is the optimized image or the original image
            referenceDensity: // [number] The density we are comparing from
            fileSize: // [number] Weight of the reference image
            recommendedMaxDensity: // [number] The density above which the human eye hardly sees a difference
            recommendedWidth: // [number] Corresponding dimensions in pixels
            recommendedHeight: // [number] Corresponding dimensions in pixels
            newFileSize: // [number] Weight in bytes after resizing

        },
        // Appears only if the image could be significantly smaller if re-encoded in a new format (WebP or AVIF)
        imageOldFormat: {
            currentFormat: // [string] Type of the original file
            fileSize: // [number] Weight in bytes of the original file
            newFileSize: // [number] Weight in bytes of the best found format
            webpSize: // [number] Weight in bytes in WebP
            avifSize: // [number] Weight in bytes in AVIF
        },
        // Appears only if the sizes parameter on a responsive image is more than 10% smaller or larger compared to the onscreen dimensions (only for images with a "w" srcset)
        imageWithIncorrectSizesParam: {
            sizesAttribute: // [string] The sizes attribute extracted from the HTML
            convertedInPx: // [number] The number of pixels calculated from the sizes attribute
            displayWidth: // [number] The number of pixels the image is displayed on (same as browserdata.displayWidth)
        }
    },
    generator: // [string] Name and version of the current tool (i.e. `analyze-image vX.X.X`)
}

Error codes

| 252 | the provided image is empty | | 253 | the provided image is not a valid image |