obartra / ssim

🖼🔬 JavaScript Image Comparison
http://obartra.github.io/ssim
MIT License
298 stars 14 forks source link

RangeError: Invalid array length #295

Closed gomisha closed 2 years ago

gomisha commented 3 years ago

I'm getting an error when running a simple test on 2 files.

Environment:

Node v14.16.0 MacOS 10.13.6 (High Sierra)

Test code:

const { default: ssim } = require('ssim.js')

fs = require('fs')

const baselineImage = fs.readFileSync('./image1-1280_722.png')
const compareImage = fs.readFileSync('./image2-1280_722.png')

const { mssim, performance } = ssim(baselineImage, compareImage, { downsample: 'fast' });

console.log('SSIM: ${mssim} (${performance}ms)');

Output:

/Users/user_name/dev/antitrack/node_modules/ssim.js/dist/matlab/rgb2gray.js:48
    var array = new Array(width * height);
                ^

RangeError: Invalid array length
    at Object.rgb2grayInteger (/Users/user_name/dev/antitrack/node_modules/ssim.js/dist/matlab/rgb2gray.js:48:17)
    at toGrayScale (/Users/user_name/dev/antitrack/node_modules/ssim.js/dist/index.js:69:26)
    at ssim (/Users/user_name/dev/antitrack/node_modules/ssim.js/dist/index.js:91:39)
    at Object.<anonymous> (/Users/user_name/dev/antitrack/ssim.js/ssimjs-test.js:16:32)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47
Monder87 commented 3 years ago

i got the same issue

obartra commented 3 years ago

Does this occur with all downsampling approaches or is it only for "fast"? Looking at the error I'm guessing width or height ends up not being read correctly. Are you able to look into this in more detail?

atjn commented 3 years ago

AFAICT this error occurs because you are passing a raw encoded image to ssim but it expects an ImageData object with a decoded bitmap plus width and height properties:

https://github.com/obartra/ssim/blob/3f3af6118c78b3ed4f0ff6eb224700c071f29c99/src/types.ts#L18-L22

The error is just the first of many. It crashes because the width and height properties are both undefined.

I encountered this same error when I started using this library, and it took me quite a while to figure out what was wrong. Maybe a better error description could be returned in this case and/or the documentation could be better at describing exactly what data the library is expecting as input?

obartra commented 3 years ago

That's a good point, yeah down to add any improved messaging if anyone wants to contribute a PR. There's some documentation on how to load for web and node in the wiki here as well

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

CookGuo commented 3 years ago

i got the same issue

obartra commented 3 years ago

I'm unable to work on it at the moment but I'll accept a fix if you are willing to contribute one

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

TalkLounge commented 1 year ago

Workaround:

const { ssim } = require("ssim.js");
const { createCanvas, loadImage } = require("canvas");

async function generateImageData(file) {
    const image = await loadImage(file);
    const canvas = createCanvas(image.width, image.height);
    const context = canvas.getContext('2d');
    context.drawImage(image, 0, 0);
    return {
        data: context.getImageData(0, 0, image.width, image.height).data,
        width: image.width,
        height: image.height
    };
}

async function init() {
    console.log(ssim(await generateImageData("C:/img1.jpg"), await generateImageData("C:/img2.jpg")));
}

init();