├── UFace ├── public │ ├── images │ │ ├── jz.png │ │ └── face │ │ │ ├── 1.jpg │ │ │ └── timg.jpg │ ├── files │ │ ├── BI850i1k5ERRXh862wv2-jdl.jpg │ │ ├── HqwCAAPIaJjHSyUEocoaUAJy.jpg │ │ └── kQIVreuY3OtPDiUTu19eqNln.jpg │ ├── stylesheets │ │ └── style.css │ └── js │ │ └── index.js ├── views │ ├── error.ejs │ └── index.ejs ├── node_modules │ └── baidu-ai │ │ └── aip-node-sdk-1.1.0.zip ├── routes │ ├── users.js │ └── index.js ├── package.json ├── app.js └── bin │ └── www └── README.md /UFace/public/images/jz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/jz.png -------------------------------------------------------------------------------- /UFace/public/images/face/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/face/1.jpg -------------------------------------------------------------------------------- /UFace/views/error.ejs: -------------------------------------------------------------------------------- 1 |

<%= message %>

2 |

<%= error.status %>

3 |
<%= error.stack %>
4 | -------------------------------------------------------------------------------- /UFace/public/images/face/timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/images/face/timg.jpg -------------------------------------------------------------------------------- /UFace/public/files/BI850i1k5ERRXh862wv2-jdl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/BI850i1k5ERRXh862wv2-jdl.jpg -------------------------------------------------------------------------------- /UFace/public/files/HqwCAAPIaJjHSyUEocoaUAJy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/HqwCAAPIaJjHSyUEocoaUAJy.jpg -------------------------------------------------------------------------------- /UFace/public/files/kQIVreuY3OtPDiUTu19eqNln.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/public/files/kQIVreuY3OtPDiUTu19eqNln.jpg -------------------------------------------------------------------------------- /UFace/node_modules/baidu-ai/aip-node-sdk-1.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bubucuo/uface-baidu-ai/HEAD/UFace/node_modules/baidu-ai/aip-node-sdk-1.1.0.zip -------------------------------------------------------------------------------- /UFace/public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 50px; 3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; 4 | } 5 | 6 | a { 7 | color: #00B7FF; 8 | } 9 | -------------------------------------------------------------------------------- /UFace/routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res, next) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /UFace/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "uface", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "body-parser": "~1.17.1", 10 | "cookie-parser": "~1.4.3", 11 | "debug": "~2.6.3", 12 | "ejs": "~2.5.6", 13 | "express": "~4.15.2", 14 | "morgan": "~1.8.1", 15 | "serve-favicon": "~2.4.2", 16 | "multiparty": "latest" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /UFace/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= title %> 5 | 6 | 7 | 8 | 9 |

<%= title %>

10 |

Welcome to <%= title %>

11 |
12 | 13 | 14 |
15 | 16 |
17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /UFace/public/js/index.js: -------------------------------------------------------------------------------- 1 | function uploadImg() { 2 | var formData = new FormData(); 3 | formData.append("file", $("#upload")[0].files[0]); 4 | $.ajax({ 5 | type: 'POST', 6 | url: './file/uploading', 7 | data: formData, 8 | processData: false, 9 | contentType: false, 10 | success: function(res) { 11 | var json = JSON.parse(res) 12 | if(json.result&&json.result.length>0) { //从后端获取到人脸检测到结果后,调用createFace函数,进行图片合成 13 | createFace(json); 14 | } else { 15 | alert("检测不到人脸,请上传符合规格的头像!") 16 | } 17 | } 18 | }); 19 | }; 20 | 21 | function createFace(data) { 22 | var jzimg = $('#jz')[0]; 23 | var img = $('#target')[0]; 24 | var canvas = $('#canvas')[0]; 25 | var ctx = canvas.getContext('2d'); 26 | var location = data.result[0] 27 | var sx = location.location.left, 28 | sy = location.location.top, 29 | swidth = location.location.width, 30 | sheight = location.location.height; 31 | img.src = data.imgSrc 32 | img.onload = function() { //异步 33 | ctx.drawImage(jzimg, 0, 0); 34 | ctx.drawImage(img, sx, sy, swidth, sheight, 210, 68, 70, 48); 35 | } 36 | }; -------------------------------------------------------------------------------- /UFace/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var favicon = require('serve-favicon'); 4 | var logger = require('morgan'); 5 | var cookieParser = require('cookie-parser'); 6 | var bodyParser = require('body-parser'); 7 | 8 | var index = require('./routes/index'); 9 | var users = require('./routes/users'); 10 | 11 | var app = express(); 12 | 13 | // view engine setup 14 | app.set('views', path.join(__dirname, 'views')); 15 | app.set('view engine', 'ejs'); 16 | 17 | // uncomment after placing your favicon in /public 18 | //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); 19 | app.use(logger('dev')); 20 | app.use(bodyParser.json()); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | app.use(cookieParser()); 23 | app.use(express.static(path.join(__dirname, 'public'))); 24 | 25 | app.use('/', index); 26 | app.use('/users', users); 27 | 28 | // catch 404 and forward to error handler 29 | app.use(function(req, res, next) { 30 | var err = new Error('Not Found'); 31 | err.status = 404; 32 | next(err); 33 | }); 34 | 35 | // error handler 36 | app.use(function(err, req, res, next) { 37 | // set locals, only providing error in development 38 | res.locals.message = err.message; 39 | res.locals.error = req.app.get('env') === 'development' ? err : {}; 40 | 41 | // render the error page 42 | res.status(err.status || 500); 43 | res.render('error'); 44 | }); 45 | 46 | module.exports = app; 47 | -------------------------------------------------------------------------------- /UFace/routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET home page. */ 5 | router.get('/', function(req, res, next) { 6 | res.render('index', { title: 'Express' }); 7 | }); 8 | router.post('/', function(req, res, next) { 9 | res.send('UFace post ok') 10 | }); 11 | 12 | 13 | var AipFace = require("baidu-ai").face; 14 | 15 | var APP_ID = "9964551"; 16 | var API_KEY = "fCTk95tO6MIKgROeBhBEigcD"; 17 | var SECRET_KEY = "E8Ij9ftcDMhu5h2b898TzzYzem0161Dc"; 18 | //这三个key记得替换为你申请的appid 19 | 20 | var client = new AipFace(APP_ID, API_KEY, SECRET_KEY); 21 | 22 | /*var fs = require('fs'); 23 | var image = fs.readFileSync('./public/images/face/face.png'); 24 | var base64Img = new Buffer(image).toString('base64'); 25 | 26 | client.detect(base64Img).then(function(result) { 27 | console.log(JSON.stringify(result)); 28 | });*/ 29 | 30 | var multiparty = require('multiparty'); 31 | var util=require('util'); 32 | var fs = require('fs'); 33 | 34 | router.post('/file/uploading', function(req, res, next) { 35 | 36 | var form = new multiparty.Form({ 37 | uploadDir: './public/files/' 38 | }); 39 | 40 | form.parse(req, function(err, fields, files) { 41 | var filesTmp = JSON.stringify(files, null, 2); 42 | 43 | if (err) { 44 | console.log('parse error: ' + err); 45 | } else { 46 | console.log('parse files: ' + filesTmp); 47 | 48 | var inputFile = files.file[0]; 49 | var uploadedPath = inputFile.path; 50 | 51 | var image = fs.readFileSync(uploadedPath); 52 | var base64Img = new Buffer(image).toString('base64'); 53 | 54 | 55 | 56 | client.detect(base64Img).then(function(result) { 57 | Object.assign(result, { 58 | imgSrc: uploadedPath.replace('public','').replace(/\\/g, '/') 59 | }) 60 | res.send(JSON.stringify(result)); 61 | }); 62 | 63 | }; 64 | 65 | }); 66 | 67 | }); 68 | 69 | module.exports = router; 70 | -------------------------------------------------------------------------------- /UFace/bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var app = require('../app'); 8 | var debug = require('debug')('uface:server'); 9 | var http = require('http'); 10 | 11 | /** 12 | * Get port from environment and store in Express. 13 | */ 14 | 15 | var port = normalizePort(process.env.PORT || '3000'); 16 | app.set('port', port); 17 | 18 | /** 19 | * Create HTTP server. 20 | */ 21 | 22 | var server = http.createServer(app); 23 | 24 | /** 25 | * Listen on provided port, on all network interfaces. 26 | */ 27 | 28 | server.listen(port); 29 | server.on('error', onError); 30 | server.on('listening', onListening); 31 | 32 | /** 33 | * Normalize a port into a number, string, or false. 34 | */ 35 | 36 | function normalizePort(val) { 37 | var port = parseInt(val, 10); 38 | 39 | if (isNaN(port)) { 40 | // named pipe 41 | return val; 42 | } 43 | 44 | if (port >= 0) { 45 | // port number 46 | return port; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | /** 53 | * Event listener for HTTP server "error" event. 54 | */ 55 | 56 | function onError(error) { 57 | if (error.syscall !== 'listen') { 58 | throw error; 59 | } 60 | 61 | var bind = typeof port === 'string' 62 | ? 'Pipe ' + port 63 | : 'Port ' + port; 64 | 65 | // handle specific listen errors with friendly messages 66 | switch (error.code) { 67 | case 'EACCES': 68 | console.error(bind + ' requires elevated privileges'); 69 | process.exit(1); 70 | break; 71 | case 'EADDRINUSE': 72 | console.error(bind + ' is already in use'); 73 | process.exit(1); 74 | break; 75 | default: 76 | throw error; 77 | } 78 | } 79 | 80 | /** 81 | * Event listener for HTTP server "listening" event. 82 | */ 83 | 84 | function onListening() { 85 | var addr = server.address(); 86 | var bind = typeof addr === 'string' 87 | ? 'pipe ' + addr 88 | : 'port ' + addr.port; 89 | debug('Listening on ' + bind); 90 | } 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # uface-baidu-ai 2 | 人民日报的换军装,利用了baidu-ai、canvas、node、express 3 | 4 | 主要参考:https://www.youyong.top/article/11597fcc6b4ee?yyfr=sf,这里大神有些小细节没有写,由于我还是小白,看了很久,才把代码全部写出来。因此写出了详细的步骤,有不懂的可以再私信我 bubucuovinci@163.com,目前只是写出了最简单的一部分,接下来再调整整体脸色。 5 | 6 | 环境搭建(主要来自https://www.youyong.top/article/11597fcc6b4ee?yyfr=sf,稍有补充): 7 | 1. express -e ejs UFace (没有express的需要事先安装),生成的package.json中最后加一个"multiparty": "latest",这个在最后上传图片(3.7步骤)的时候需要依赖。 8 | 2. 调通后端接口: 9 | 2.0 UFace目录下安装依赖文件,npm install,生成node_modules文件夹 10 | 2.1 找到 views/index.ejs 文件,添加 11 | 12 | 2.2 找到routes/index.js文件,添加 13 | router.post('/', function(req, res, next) { 14 | res.send('UFace post ok') 15 | }); 16 | 17 | 2.3 终端输入 node bin/www 18 | 浏览器访问:http://localhost:3000/ 19 | 20 | 2.4 打开开发者工具,在console里调试接口,输入: 21 | $.post("/", function(data) { 22 | console.log(data); 23 | }); 24 | 看到控制台打印出:UFace post ok 25 | 自此,我们的前后端调通了。 26 | 3. 百度ai人脸识别环境补充 27 | 3.0 UFace/node_modules下面新建文件夹baidu-ai 28 | 3.1 下载node SDK压缩包,下载地址:http://ai.baidu.com/sdk#sdk-category-bfr 29 | 3.2 UFace/node_modules/baidu-ai下解压aip-node-sdk-1.1.0.zip,选择解压到当前文件夹即可,在该文件夹下npm install,安装sdk依赖库 30 | 3.3 在百度AI中申请好APPID;就是右上角的控制台处,然后页面下方点击人脸识别,创建应用或者管理应用。地址:https://console.bce.baidu.com/ai/?fromai=1#/ai/face/app/list 31 | 3.4 继续到routes/index.js文件中,加入 32 | 33 | var AipFace = require("baidu-ai").face; 34 | 35 | var APP_ID = "9964551"; 36 | var API_KEY = "fCTk95tO6MIKgROeBhBEigcD"; 37 | var SECRET_KEY = "E8Ij9ftcDMhu5h2b898TzzYzem0161Dc"; 38 | //这三个key记得替换为你申请的appid 39 | 40 | var client = new AipFace(APP_ID, API_KEY, SECRET_KEY); 41 | (注意:routes中文件更改的话,node bin/www命令需重启) 42 | 3.5 上传本地的一张图片,调试下百度AI接口 43 | 44 | var fs = require('fs'); 45 | var image = fs.readFileSync('./public/images/face/face.png'); 46 | var base64Img = new Buffer(image).toString('base64'); 47 | 48 | client.detect(base64Img).then(function(result) { 49 | console.log(JSON.stringify(result)); 50 | }); 51 | 终端打印出获取到的结果,接口获取成功。 52 | 3.6 找到 views/index.ejs 文件,添加 53 | 然后在javascripts中添加index.js文件,具体代码参看文件 54 | 3.7 找到routes/index.js文件,添加 55 | var multiparty = require('multiparty'); 56 | var util=require('util'); 57 | var fs = require('fs'); 58 | 59 | router.post('/file/uploading', function(req, res, next) { 60 | 61 | var form = new multiparty.Form({ 62 | uploadDir: './public/files/' 63 | }); 64 | 65 | form.parse(req, function(err, fields, files) { 66 | var filesTmp = JSON.stringify(files, null, 2); 67 | 68 | if (err) { 69 | console.log('parse error: ' + err); 70 | } else { 71 | console.log('parse files: ' + filesTmp); 72 | 73 | var inputFile = files.file[0]; 74 | var uploadedPath = inputFile.path; 75 | 76 | var image = fs.readFileSync(uploadedPath); 77 | var base64Img = new Buffer(image).toString('base64'); 78 | 79 | client.detect(base64Img).then(function(result) { 80 | res.send(JSON.stringify(result)); 81 | }); 82 | 83 | }; 84 | 85 | }); 86 | 87 | }); 88 | 3.8 UFace/public中新建files文件,存放生成的图片 89 | 3.9 UFace/public中我存放了一张脸部透明的军装照片,UFace/public/javascripts/index.js中参数是按照这张军装照片的写的,如果你想换照片,参数也需要更换。 90 | face文件夹中我存了两张大头贴,当然你也可以自己找图片。 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | --------------------------------------------------------------------------------