const fs = require('fs'); const _ = require('lodash'); const PNG = require('pngjs').PNG; const { promisify } = require('util'); const md5File = require('md5-file'); const images = [ { filename: 'graphic-gif.gif' }, { filename: 'graphic-jpg-0.jpg' }, { filename: 'graphic-jpg-76.jpg' }, { filename: 'graphic-jpg-100.jpg' }, { filename: 'graphic-png.png' }, ]; for (const image of images) { image.orig = `${__dirname}/files/${image.filename}`; image.insta = image.orig.split('.')[0] + '-after.jpg'; image.instapng = image.orig.split('.')[0] + '-after-png.png'; } const getPixels = promisify((filename, callback) => { fs.createReadStream(filename) .pipe(new PNG({ colorType: 2 })) .on("parsed", function () { const pixels = []; for (var y = 0; y < this.height; y++) { for (var x = 0; x < this.width; x++) { var idx = (this.width * y + x) << 2; pixels.push({ r: this.data[idx + 0], g: this.data[idx + 1], b: this.data[idx + 2], }); } } callback(null, pixels); }); }); const comparePixels = (e1, e2) => { const rmean = (e1.r + e2.r) / 2; const r = e1.r - e2.r; const g = e1.g - e2.g; const b = e1.b - e2.b; const v = Math.sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)); const perc = Math.min(1, Math.max(v / 764, 0)); return perc; // 0 is identical, 1 is opposite }; (async () => { // const origPixels = await getPixels('./files/photoshop-png.png'); const origPixels = await getPixels('./files/graphic-png.png'); for (const image of images) { const imgPixels = await getPixels(image.instapng); let percentDiff = 0; for (const [i, aPixel] of origPixels.entries()){ const bPixel = imgPixels[i]; const pixelDiff = comparePixels(aPixel, bPixel); percentDiff += pixelDiff; } percentDiff = percentDiff / origPixels.length; image.diff = percentDiff; let exactDiff = 0; for (const [i, aPixel] of origPixels.entries()){ const bPixel = imgPixels[i]; const exactSame = JSON.stringify(aPixel) === JSON.stringify(bPixel); exactDiff += exactSame ? 0 : 1; } image.exactdiff = exactDiff / origPixels.length; image.origkb = Math.round(fs.statSync(image.orig).size/1024); image.instakb = Math.round(fs.statSync(image.insta).size/1024); const origHash = await md5File(image.orig); const instaHash = await md5File(image.insta); image.hashmatch = origHash === instaHash; } // results for (const image of _.sortBy(images, i => i.diff)) { console.log([ image.filename, ((1-image.diff)*100).toFixed(4)+'%', ((1-image.exactdiff)*100).toFixed(4)+'%', image.origkb+'kb', image.instakb+'kb', image.hashmatch, ].join(',')); } })();