22 lines
1.3 KiB
JavaScript
22 lines
1.3 KiB
JavaScript
// H5-compatible face brightness: sample the detected face on a 16x16 grid,
|
|
// using the already copied/normalized RGB frame. No extra canvas or frame copy.
|
|
function finite(value) { return typeof value === 'number' && isFinite(value); }
|
|
function sample(rgb, width, height, box) {
|
|
if (!rgb || !finite(width) || !finite(height) || width < 1 || height < 1 ||
|
|
Math.floor(width) !== width || Math.floor(height) !== height || rgb.length < width * height * 3 ||
|
|
!box || ![box.x, box.y, box.width, box.height].every(finite) || box.width <= 0 || box.height <= 0) return null;
|
|
var x0 = Math.max(0, box.x), y0 = Math.max(0, box.y);
|
|
var x1 = Math.min(width, box.x + box.width), y1 = Math.min(height, box.y + box.height);
|
|
if (x1 <= x0 || y1 <= y0) return null;
|
|
var sum = 0;
|
|
for (var y = 0; y < 16; y++) for (var x = 0; x < 16; x++) {
|
|
var sx = Math.min(width - 1, Math.floor(x0 + (x + .5) * (x1 - x0) / 16));
|
|
var sy = Math.min(height - 1, Math.floor(y0 + (y + .5) * (y1 - y0) / 16));
|
|
var offset = (sy * width + sx) * 3, r = rgb[offset], g = rgb[offset + 1], b = rgb[offset + 2];
|
|
if (![r, g, b].every(finite) || r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) return null;
|
|
sum += .299 * r + .587 * g + .114 * b;
|
|
}
|
|
return sum / 256;
|
|
}
|
|
module.exports = { sample: sample };
|