みかづきブログ・カスタム

基本的にはちょちょいのほいです。

face-apiを使って、写真から顔を探してその周りを切り抜くスクリプトを作りました 😀

f:id:kimizuka:20210708002755p:plain

こんな感じで、顔の周りを切り抜くスクリプトを書きました。

github.com

(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;
  }
})();

  1. webpackなどを使わずさくっとつくりたかった
  2. なるべく古い端末でも動くようにしたかった。

の2点から、なるべく古い書き方で書きました。
これと同じ方針です。

blog.kimizuka.org

ただ、window.trimAndResizeとしているのは良くないので、直すかもしれません。

機能としては、

  1. 写真の中から顔っぽいものを探す
  2. 複数見つかった場合は一番顔っぽいものを選択する
  3. 顔っぽいものの周りを切り出す
  4. 顔っぽいものが見つからない場合はセンターを切り出す

という挙動を実装したつもりです。

顔の検出には、face-apiを使っています。

github.com