Closed TheDogHusky closed 2 years ago
Hello. Hmm this is weird. Which version of node and looks-same you use? Can you send your images which you compare?
I have the same issue. Using the latest version of looks-same (8.0.0) with nodejs v16.17.0
I'm running the simple example there is in README file. like this..
var looksSame = require('looks-same');
looksSame('image1.png', 'image2.png', function(error, {equal}) {
// equal will be true, if images looks the same
console.log(equal)
});
But I got nothing
Hello. Hmm this is weird. Which version of node and looks-same you use? Can you send your images which you compare?
Node.JS 16.14.0 Looksame lastest
Since version 8.0.0 callback support has been removed in favor of promises
use this
var { equal } = await looksSame('image1.png', 'image2.png');
Oh yeah, thank you very much, i'll test out and tell if it works now
Now I get this error:
Error: Invalid file signature
at module.exports.Parser._parseSignature (D:\Utilisateurs\Adam\Documents\dev\JavaScript\nekodownloader\node_modules\pngjs\lib\parser.js:48:18)
at module.exports.ChunkStream._processRead (D:\Utilisateurs\Adam\Documents\dev\JavaScript\nekodownloader\node_modules\pngjs\lib\chunkstream.js:160:13)
at module.exports.ChunkStream._process (D:\Utilisateurs\Adam\Documents\dev\JavaScript\nekodownloader\node_modules\pngjs\lib\chunkstream.js:175:14)
New code:
/**
*
* @param {string} one
* @param {string} two
* @returns {boolean}
*/
isSameImg(one, two) {
let isEqual;
looksSame(
one,
two,
).then(res => {
isEqual = res.equal;
});
return isEqual;
};
Using Looks-Same version 8.0.1 (lastest)
Error: Invalid file signature
Usually this error is reproduced when used git lfs and for some reason lfs pointers not resolved to the real images. Do you use git lfs in your project? This problem is not reproduced on your images from this comment - https://github.com/gemini-testing/looks-same/issues/81#issuecomment-1252649696 using simple script:
const looksSame = require('looks-same');
(async () => {
const res = await looksSame('./first.jpeg', './second.jpeg');
console.log('res:', res);
})();
Nah all files are stored on my PC, there aint any repo for this small useless project, idk for the images i commented, i am just generating even more images
Here is the code: index.js
const Downloader = require('./structures/downloader');
const downloader = new Downloader('https://nekos.life/api/v2/img/neko', './test', 'test', true, "url");
downloader.start(500, 31).then((res) => {
console.log(['Downloader'], 'Done! Downaloded '+ res.count + 'images!');
});
process.on('uncaughtException', console.error);
process.on('uncaughtExceptionMonitor', console.error);
process.on('unhandledRejection', console.error);
structures/Downloader.js
const fs = require('fs');
const Axios = require('axios');
const { default: axios } = require('axios');
const fetch = require('node-fetch');
const path = require('path');
const looksSame = require('looks-same');
/**
* @typedef {Object} Result
* @property {number} count
*/
/**
*
* @param {string} url
* @param {string} filepath
* @returns {Promise<string>}
*/
async function downloadImage(url, filepath) {
const response = await Axios({
url,
method: 'GET',
responseType: 'stream'
});
return new Promise((resolve, reject) => {
response.data.pipe(fs.createWriteStream(filepath))
.on('error', reject)
.once('close', () => resolve(filepath));
});
}
function getDirname(dirpath) {
return path.dirname(dirpath);
}
/**
* An image downloader, from APIs
* - **WARNING: THE DOWNLOADER WORKS ONLY WITH JSON RESPONSES!!**
* @example const Downloader = require('./structures/downloader');
* const myDownloader = new Downloader('https://nekos.life/api/v2/img/neko', './nekos', 'neko', true, "url");
* myDownloader.start(100, 0);
* @author ClassyCrafter<contact@classy.works>
* @version 1.0.0
*/
class Downloader {
/**
*
* @param {string} url The url to the api to download images from
* @param {string} dirpath The path to the directory to save the files to
* @param {string} type The type (filename) of the files (Example: "neko" will do "neko-0001.<extension>")
* @param {boolean} verify If we verify every image, could be long with big numbers
* @param {string} imgUrlParameter The parameter to get the image url from the api (example: "url"), from the JSON response
*/
constructor(url, dirpath, type, verify, imgUrlParameter) {
this.url = url;
this.dirpath = dirpath;
this.type = type;
this.verify = verify;
this.dirname = getDirname(dirpath);
this.imgUrlParameter = imgUrlParameter;
const images = fs.readdirSync(this.dirpath);
const paths = [];
images.forEach(img => {
paths.push(path.join(__dirname, '..', this.dirname, img));
});
this.imgs = paths;
};
/**
* Formats the number
* @param number The number to format
* @returns {string|*} The formatted number
*/
formatNumber(number) {
switch (number) {
case number < 10:
return `000${number}`;
case number < 100:
return `00${number}`;
case number < 1000:
return `0${number}`;
default:
return number;
}
};
/**
* Downloads the image
* @param url The url to the image
* @param file The filename to save the image as
* @returns {Promise<string>} The path to the image
*/
async download(url, file) {
return await downloadImage(url, `${this.dirpath}/${file}`);
};
/**
* Generates the filename
* @param count The number to start counting from
* @returns {string} The formatted filename
*/
generateFileName(count) {
return `${this.type}-${count}`;
};
/**
* If the image exists
* @param filename The filename of the image
* @returns {boolean} If the image exists
*/
existsImg(filename) {
return fs.existsSync(path.join(this.dirpath, filename));
};
/**
*
* @param {string} one First image path or name
* @param {string} two Second image path or name
* @returns {boolean} If the images are the same
*/
isSameImg(one, two) {
let isEqual;
looksSame(
one,
two,
).then(res => {
isEqual = res.equal;
});
return isEqual;
};
/**
* Starts the download
* @param number The number of images to download
* @param count The number to start counting from
* @returns {Promise<Result>}
*/
async start(number, count) {
let resCount;
for (let i = count; i < (count + number + 1); i++) {
count = i;
const fileNumber = this.formatNumber(i);
let file = this.generateFileName(fileNumber);
if(this.existsImg(file)) {
count++;
continue;
}
const url = await fetch(this.url)
.then(res => res.json())
.then(json => json[this.imgUrlParameter]);
const extension = "." + url.split('.').pop();
file = file + extension;
const imgPath = await this.download(url, file);
console.log(['downloader'], `Downloaded ${file}`);
if (this.verify) {
this.imgs.forEach(pathLike => {
const imgName = pathLike;
const secondImgName = path.resolve(imgPath);
const isSame = this.isSameImg(imgName, secondImgName);
if (isSame) {
fs.unlinkSync(imgPath);
console.log(['downloader'], `File ${file} deleted, it was the same as the other.`);
i--;
}
});
}
}
return {
count: resCount
}
};
}
module.exports = Downloader;
It looks like you are trying to compare not only png image but also jpeg and jpg which can be parsed incorrectly by pngjs which used in looks-same. Soon we will move to sharp and most likely there will be no such problem. In your case I suggest converting images to png.
Moreover you have a bug in your code:
isSameImg(one, two) {
let isEqual;
looksSame(
one,
two,
).then(res => {
isEqual = res.equal;
});
return isEqual;
};
You don't wait when promise resolved. I suggest rewrite it to:
async isSameImg(one, two) {
let isEqual;
const {equal} = await looksSame(
one,
two,
);
return equal;
};
// ...
const isSame = await this.isSameImg(imgName, secondImgName);
Yeah I need to compare PNG, JPEG, GIFs and a lot of other image files.
Yeah I need to compare PNG, JPEG, GIFs and a lot of other image files.
Currently this library is intended only for png comparison. It's also mentioned in the package description. In the near future looks-same
will work also with other types of images.
So I close this issue.
I'll wait for you to moove to sharp then, ty for your support anyways
this function is in a class I use, when i use the function I get "TypeError: Cannot read properties of undefined (reading 'equal')" wich means res is undefined, and testing with function(err, { equal } will return me I can't destructure the object cause it's undefined.
any ideas?