-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
104 lines (76 loc) · 2.64 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
"use strict";
const FD = require( 'face-detect' );
const Canvas = require( 'canvas' );
const fs = require( 'fs' );
const Log = require( 'debug' )( "facecrop" );
const Image = Canvas.Image;
const process = ( options ) => new Promise( ( resolve, reject ) => {
if ( !options.src || !options.dst ) return reject( new Error( '"src" and "dst" options required' ) )
options = Object.assign( {
scale: 1,
force: false
}, options );
Log( options );
let img = new Image();
img.onerror = ( err ) => {
reject( err );
};
img.onload = () => {
let w = img.width;
let h = img.height;
let canvas = new Canvas( w, h );
let ctx = canvas.getContext( '2d' );
ctx.drawImage( img, 0, 0, w, h, 0, 0, w, h );
let faces = FD.detect_objects( {
"canvas": canvas,
"interval": 5,
"min_neighbors": 1
} );
if ( faces.length == 0 && !options.force ) return reject( new Error( 'No faces detected' ) );
Log( faces );
let face = faces.sort( ( a, b ) => b.confidence - a.confidence )[ 0 ];
Log( face );
if(!face) face = {
x: 0,
y: 0,
width: w,
height: h
}
face.cX = face.x + face.width / 2;
face.cY = face.y + face.height / 2;
let ratio = face.width / face.height;
if ( options.dst.width || options.dst.height ) {
ratio = options.dst.width / options.dst.height;
options.dst.width = options.dst.width || options.dst.height;
options.dst.height = options.dst.height || options.dst.width;
if ( ratio > 1 ) face.width = face.height * ratio;
if ( ratio < 1 ) face.height = face.width / ratio;
if ( ratio == 1 ){
let max = Math.max(face.width, face.height);
face.width = max;
face.height = max;
}
};
let width = face.width * options.scale;
let height = face.height * options.scale;
let coverRatio = Math.max(width / w, height / h);
if(coverRatio > 1){
width = width / coverRatio;
height = height / coverRatio;
}
let X = Math.max( 0, face.cX - width / 2 );
let Y = Math.max( 0, face.cY - height / 2 );
Log( X, Y, width, height );
let outWidth = options.dst.width || width;
let outHeight = options.dst.height || height;
let outCanvas = new Canvas( outWidth, outHeight );
let outCtx = outCanvas.getContext( '2d' );
outCtx.imageSmoothingEnabled = true;
outCtx.drawImage( img, X, Y, width, height, 0, 0, outWidth, outHeight );
let out = fs.createWriteStream( options.dst.path );
out.on( 'finish', () => resolve( options.dst.path ) );
outCanvas.pngStream().pipe( out );
};
img.src = options.src;
} );
module.exports = process;