UNPKG

crescent

Version:

JavaScript images Binarization/Comparsion

131 lines (129 loc) 3.99 kB
export class Results extends Array { constructor(arr) { super(...arr); this.debug = (context) => { if (typeof context.open != "function") return; if (this.length == 0) return; let canvas = document.createElement('canvas'); canvas.width = this[0].frame.width * 5; canvas.height = this[0].frame.height * this.length; let ctx = canvas.getContext('2d'); ctx.fillStyle = "white"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; this.map((result, i) => { ctx.putImageData( new ImageData(result.diff, result.frame.width, result.frame.height), 0, result.frame.height * i, 0, 0, result.frame.width, result.frame.height ); ctx.font = "12px Helvetica"; ctx.fillText( `${result.score}`, result.frame.width + 8, result.frame.height * (i + 1) - 2 ); }); const uri = canvas.toDataURL(); window.open(uri); } } /* XXX: why it doesn't work? debug(context) { } */ } export default class Picture { constructor(data) { this.canvas = document.createElement('canvas'); let img = new Image(); this.initialized = new Promise(resolve => { img.onload = () => { this.canvas.width = img.width; this.canvas.height = img.height; this.frame = { width: img.width, height: img.height }; let ctx = this.canvas.getContext('2d'); ctx.drawImage(img, 0, 0, img.width, img.height); this.bytes = ctx.getImageData(0, 0, img.width, img.height).data; // For Safari if (this.bytes.slice !== 'function') this.bytes.slice = Array.prototype.slice; resolve(this); }; }); img.src = data; } static init(data) { let pic = new Picture(data); return pic.initialized; } hello() { return 'hello, this is crescent.Image'; } getBrightness(r, g, b, a) { return ((r + g + a) / 3) * (a/255); } binarize(threshold = 140) { for (let i = 0; i < this.bytes.length; i += 4) { const brightness = this.getBrightness(...this.bytes.slice(i, i+4)); if (brightness > threshold) { this.bytes[i] = this.bytes[i+1] = this.bytes[i+2] = 255; // WHITE } else { this.bytes[i] = this.bytes[i+1] = this.bytes[i+2] = 0; // BLACK } // anyway this.bytes[i+3] = 255; } this.binarized = true; // console.log(this.bytes); return this; } chunks() { let pool = []; for (let i = 0; i < this.bytes.length; i += 4) { pool.push(this.bytes.slice(i, i+4)); } return pool; } compareTo(...pics) { const tasks = pics.map(pic => { return this.compare(pic) }); return Promise.all(tasks).then(results => { return Promise.resolve(new Results(results)); }); } compare(pic) { const _mychunks = this.chunks(); const yourchunks = pic.chunks(); let diffchunks = Uint8ClampedArray.from(this.bytes); if (this.binarized) { const totalscore = _mychunks.map((chunk, i) => { const abs = Math.abs(chunk[0] - yourchunks[i][0]); diffchunks[i * 4 + 0] = abs; diffchunks[i * 4 + 1] = abs; diffchunks[i * 4 + 2] = abs; diffchunks[i * 4 + 3] = 255; return abs; }).reduce((total, score) => { return total + score; }) / _mychunks.length; return Promise.resolve({ frame: {...this.frame}, diff: diffchunks, score: (255 - totalscore) / 255 }); } return Promise.resolve({}); } debug() { this.open = () => { let ctx = this.canvas.getContext('2d'); ctx.putImageData(new ImageData(this.bytes, this.canvas.width, this.canvas.height), 0, 0); const uri = this.canvas.toDataURL(); if (window && typeof window.open == 'function') window.open(uri); else console.log(uri); return Promise.resolve(); } return this; } }