ある作業のため画像中のHSV値が欲しくなりまして。
それくらいのアプリなら転がっているだろうな。。。と思ったんですが、ちょいと自作しようと思ってハマりました。完成まで2時間くらいかかったような。。。
一応、完成したアプリは以下のような感じです。ローカルにあるファイルを選択してアップロードしまして、あとは画像上でマウスカーソルを動かすとその場所にあるHSVを取得して表示してくれます。なんか動作がおかしいのですが。。。とりあえずHUEは取れていそう。
https://editor.p5js.org/keiichi.takahashi@gmail.com/present/6OqOih90j
ちなみにコードは以下です。p5.dom.jsを使っています。
let img; var h, s, v; function handleFile(file) { if (file.type === 'image') { img = loadImage(file.data, imageLoaded); //★1 } else { img = null; } } function setup() { div_h = createDiv(); div_s = createDiv(); div_v = createDiv(); input = createFileInput(handleFile); // input.position(0, 0); } function draw() { colorMode(HSB, 255); pixel = get(mouseX, mouseY); h = hue(pixel); s = saturation(pixel); v = brightness(pixel); div_h.html("H: " + h); div_s.html("S: " + s); div_v.html("V: " + v); stroke(h, s, v); strokeWeight(3); noFill(); rect(0, 0, width-1, height-1); } function imageLoaded() { //★2 resizeCanvas(img.width*2, img.height*2); scale(2); image(img, 0, 0); }
はまった場所は★1でした。
ページ中にFile選択用の要素を追加するのはcreateFileInputでできるのですが、このサンプルには以下のように書かれているんですね。
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); //★3 img.hide(); } else { img = null; } }
この★3のcreateImageが曲者?のようで、P5やP55経験者からするとPImageのオブジェクトが得られると思うんですが、どうやらimageタグのポインタのようなものが得られるだけでPImageのような操作ができないんですね。。。いったいどうすればいいんだ。。。と調べたり試したりすること1時間くらい。loadImagを使えばいいってところまではすぐに行ったんです。でも、なぜか、loadImageで取得したimgオブジェクトのwidthとheightが1と返ってきて画像が表示されへん。。。という状況に。
ここから調べること1時間。やっと見つけたのが以下の書込み。ほんま助かりますわぁ〜。えせ関西弁すんまへん。さすが頼りになるのはstackoverflowさん(というかその利用者)です。
javascript - correct way to use loadImage in p5.js? - Stack Overflow
imageLoaded(←別に名前はなんでもよか)というコールバック関数をloadImage関数の第2引数に与えてやると、ブラウザ(というかdomか?)に画像ファイルをローディング完了した時点でその関数が呼ばれるようで、そこにimage関数を指定してやるとうまくいきました。上記コードの★2の部分ですね。
本題の作業は全然進んでいませんが。。。とりあえず1歩前進ってところでした。