こんな感じで、顔の周りを切り抜くスクリプトを書きました。
(function() { window.trimAndResize = trimAndResize; function trimAndResize(canvas, size) { return faceapi.nets.tinyFaceDetector.load('https://justadudewhohacks.github.io/face-api.js/models').then(function() { return faceapi.detectAllFaces(canvas, new faceapi.TinyFaceDetectorOptions()).then(function(list) { if (list.length) { return render(list, canvas, size); } return resize(trim(canvas), size); }).catch(function(err) { console.error(err); }); }).catch(function(err) { console.error(err); }); } function render(list, src, size) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var face = list[0]; canvas.width = Math.min(face.box.width * 2, src.width); canvas.height = Math.min(face.box.height * 2, src.height); ctx.drawImage( src, Math.max(Math.min(face.box.width / 2 - face.box.left, 0), canvas.width - src.width), Math.max(Math.min(face.box.height / 2 - face.box.top, 0), canvas.height -src.height) ); return resize(trim(canvas), size); } function trim(canvas) { var squareCanvas = document.createElement('canvas'); var squareCtx = squareCanvas.getContext('2d'); var size = Math.min(canvas.width, canvas.height); squareCanvas.width = squareCanvas.height = size; squareCtx.drawImage( canvas, (squareCanvas.width - canvas.width) / 2, (squareCanvas.height - canvas.height) / 2 ); return squareCanvas; } function resize(canvas, size) { var resizeCanvas = document.createElement('canvas'); var resizeCtx = resizeCanvas.getContext('2d'); var size = Math.min(size, 320); resizeCanvas.width = resizeCanvas.height = size; resizeCtx.drawImage( canvas, 0, 0, size, size ); return resizeCanvas; } })();
- webpackなどを使わずさくっとつくりたかった
- なるべく古い端末でも動くようにしたかった。
の2点から、なるべく古い書き方で書きました。
これと同じ方針です。
ただ、window.trimAndResizeとしているのは良くないので、直すかもしれません。
機能としては、
- 写真の中から顔っぽいものを探す
- 複数見つかった場合は一番顔っぽいものを選択する
- 顔っぽいものの周りを切り出す
- 顔っぽいものが見つからない場合はセンターを切り出す
という挙動を実装したつもりです。
顔の検出には、face-apiを使っています。