memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

p5.jsでcreateFileInputでファイルアップロードして画像表示するサンプルをより使えるようにした

Javascriptでサクッとインタラクティブなアプリを作る手段といえばp5.jsが有力候補かと思います。

p5js.org

このツールを使って以下のツールを作ったのですが、このツールの明らかな欠点として、(1)使用する画像ファイルをツールのプロジェクト内に配置して、(2)コード中の画像ファイル名も自分で書き換えなければならない}、がありました。詳しくは以下に説明がありますので関心のある方は参照してください。

memorandums.hatenablog.com

で、せっかくツールもいい感じになってきたのでできるだけ多くの人(コーディング知識があまりない人)が使えるようにできたらな。。。と思ってあれこれやってました。

ぐぐると、なんとp5.jsにファイルアップロード用の関数というかメソッドが用意されていることを知りました😲 で、早速動かしてみたんです。

p5js.org

すると、本当にp5.jsでファイルアップロード用のファイルセレクタが表示されてローカルのファイルを選択するとちゃんとその画像がp5.jsで表示することができたのでした。これを使えば、上記の2つの問題点は解消できます。

p5.jsがドキュメント内で公開してくれているサンプルコードは以下です(★部は僕が追加しています)。このサンプルは動作するにはするんですが。。。画像ファイルの大きさに関わらずデフォルトキャンバスサイズ(100x100)でしか描画できません。おしい。。。

let input;
let img;

function setup() {
  input = createFileInput(handleFile);
  input.position(0, 0);
}

function draw() {
  background(255);
  if (img) {
    image(img, 0, 0, width, height);
  }
}

function handleFile(file) {
  print(file);
  if (file.type === 'image') {
    img = createImg(file.data, '');
    img.hide();
    resizeCanvas(img.width, img.height); //★
  } else {
    img = null;
  }
}

あれこれやることランチ挟んで2時間くらい。色々調べました。

同じようなことで途中挫折した方もいました。この方は3時間も費やしたそうです。。。屍が。。。

note.com

これを何とかする方法を見つけました、というのがこのエントリーの主題です。

上記の屍の方(←失礼!)も書かれている通り、どういうわけか画像は取得できているけど、img.widthやimg.heightは0になります。

createImgの戻り値はp5.Elementらしいのですが。。。

p5.jsのソースコードgithubからダウンロードして読みましたが。。。わからない。

とにかくこれまでProcessingを使ってきた記憶を騒動員しました。うまく行ったのが以下です。handleFileメソッドだけ書きます。

function handleFile(file) {
  if (file.type === 'image') {
    img = loadImage(file.data, e => {
      resizeCanvas(e.width, e.height);
    });
  } else {
    img = null;
  }
  input.remove();
}

要はcreateImgはやめてloadImageを使うことにしました。そして、恐らく画像ファイルがロードしたあとでないとサイズがわからないため0となるのだと思いますので、loadImageメソッドのドキュメントの通り、ローディングが完了してから画像オブジェクトを取り出すと。。。サイズなどがしっかり入った状態になりました。これだけです。

というより、p5.jsのサンプルを上記のような感じにすればもっと使い所が広がると思うんですよね。。。プルリクを送っておくべきか?

とりあえず自分の用途では問題が解消しましたので、とりあえず記録としてこのエントリーを書きつつ、ツール開発は続けていきたいと思います。

昨日、完成したツールもPython使わずにすべてJavascriptだけでできたらいいな。。。画像切り出しはできそうなのとExcelもJSで扱うライブラリはあるようです。あとは画像ファイルをサーバーで持たないようにする。。。これができたら、誰でもすぐに利用できるツールになります。あとはホスティング先ですが、これはgithub.ioかな。

とりあえずまったり開発を続けていきたいところです。