音声や画像を使う
これまでプログラミングの基礎的な内容を学びながらアニメーションを作ってきましたが、p5.jsにはカメラやマイクを使うなどコンピュータの高度な機能を簡単に取り入れることができるようになっています。 その中でも定番のものとして、この章では画像と音声を扱うためのライブラリを紹介します。
注意
- 今回はPCのマイクとwebカメラを使う内容があります。ブラウザから求められた場合にはこれらの使用を許可してください。
- OpenProcessing とこの教科書を同時に開いているとき、カメラがどちらか片方でしか動かない場合があるようです。その場合はウィンドウが選択できているか注意して進めてください。
- 今回のプログラムは重くなりがちなのでサンプルの読み込みが遅い場合があります。ご容赦ください。
カメラや映像ファイルを表示する
p5.js では webカメラや映像ファイルを利用できます。 これらは映像の情報源が違うだけで、どちらも同じような扱いになります。
カメラの映像を使う
次のプログラムはウェブカメラから取得した映像を表示するだけのプログラムです。
let capture;
function setup() {
createCanvas(windowWidth, windowHeight);
capture = createCapture(VIDEO);
capture.hide();
// カメラ自体の解像度(画素数)
print(capture.width);
print(capture.height);
}
function draw() {
let frame = capture.get();
image(frame, 0, 0, height*(capture.width/capture.height), height);
}
カメラの映像を使用するために、まずは setup
の中で映像を管理するための機能を持つ変数を作ります。
この変数 capture
の中にはさまざまな関数が含まれていて、ドット .
を使って呼び出します。
例えば draw
の中では、カメラの画像を取り出すために get()
という関数を呼んで、 frame
に画像をコピーしています。
最後に、 image( 画像データ, 表示位置x座標, 表示位置y座標, 幅, 高さ )
で画面上に画像を配置します。
表示位置や大きさの考え方は rect()
と同じです。
余談
実はcreateCapture(VIDEO)
した時点で画面内に映像が配置されるのですが、他の図形を表示するなどdraw()
を使うこれまでのアニメーションと組み合わせられません。 これを防ぐため、setup()
内で自動的に画像を表示させないためにcapture.hide();
を使いました。 そして改めてdraw()
の中でimage
を使うという方法をとっています。
映像ファイルを使う
自分の持っている映像ファイルをアップロードして使うこともできます。 まずはエディタの右側にある Files のタブから自分の使いたい映像をアップロードしてください。
映像を読み込むには createVideo("ファイル名");
と書きます。
また、 loop()
関数で再生を開始します。
他の使い方はカメラの時と同じで、 get()
関数で画像を1フレーム取り出し、image
関数で配置します。
let vid;
let i=0;
function setup() {
createCanvas(400, 400);
vid = createVideo("fingers.mp4");
vid.loop();
vid.hide(); // hides the html video loader
}
function draw() {
let frame = vid.get();
image(frame, 0, 0, 400, 400); // redraws the video frame by frame in
i++;
if(i>400){i=0;}
circle(400 - i, 350, 48);
}
画像をフィルタで加工する
映像から取り出した画像は、 frame.filter()
のように filter()
関数を使うことで簡単に画像処理して画面に表示することができます。
数値の意味などは自分で調べましょう.
https://p5js.org/reference/#/p5/filter
let capture;
function setup() {
createCanvas(windowWidth, windowHeight);
capture = createCapture(VIDEO);
capture.hide();
// カメラ自体の解像度(画素数)
print(capture.width);
print(capture.height);
}
function draw() {
let frame = capture.get();
frame.filter(THRESHOLD, 0.4)
image(frame, 0, 0, height*(capture.width/capture.height), height);
}
次のプログラムは、画面を分割していくつかのフィルタ効果を一覧できるプログラムです。
let vid;
function setup() {
createCanvas(800, 800);
vid = createVideo("fingers.mp4");
vid.size(width/2, height/2);
vid.loop();
vid.hide(); // hides the html video loader
}
function draw() {
// normal on top left
{
let frame = vid.get();
image(frame, 0, 0); // redraws the video frame by frame in
}
// invert on top right
{
let frame = vid.get();
frame.filter(INVERT);
image(frame, width/2, 0);
}
// blur on bottom left
{
let frame = vid.get();
frame.filter(BLUR, 4);
image(frame, 0, height/2);
}
// posterization on bottom right
{
let frame = vid.get();
frame.filter(POSTERIZE, 3);
image(frame, width/2, height/2);
}
}
また、ただの関数として frame()
を使うと、画面全体に画像処理をかけることができます。
let capture;
function setup() {
createCanvas(600, 400);
capture = createCapture(VIDEO);
capture.hide();
}
function draw() {
let frame = capture.get();
image(frame, 0, 0, height*(capture.width/capture.height), height);
fill(40, 240, 240, 100);
circle(width/2, height/2, 300);
filter(POSTERIZE, 3);
}
サウンドライブラリ
音声を扱うには右側のタブから sound というライブラリを有効にする必要があります。 ライブラリとは関数をまとめたもののことで、これを読み込むことで音に関する色々な処理を使うことができます。
マイクから音を入力する
次のプログラムは拾った音声の音量にあわせて大きさが変わる円です。
let mic;
function setup() {
createCanvas(windowWidth, windowHeight);
mic = new p5.AudioIn();
mic.start();
}
function draw() {
background(150);
let vol = mic.getLevel(); // Get the overall volume (between 0 and 1.0)
circle(width/2, height/2, 100+200*vol);
}
マイクの音をもとにアニメーションを変化させたい時は、 p5.AudioIn()
を使ってマイクを制御する変数を作ります。
また、 getLevel
を呼んで音量を取得します。
音声ファイルを使う
sound ライブラリでは音声ファイルをアップロードして再生することもできます。
dingdong = loadSound('ファイル名')
のように音声ファイルを読み込み、 dingdong.play()
で再生できます。
その他の機能については ここ で調べられます。
作品で著作権などの問題がなく自由に使えるファイルを探すときには、Creative Commons license のものからさがすとよいでしょう。 "CC0 sound", "CC0 image" などで検索すると見つかります。 音声ファイルを探すときには freesound が便利です(登録が必要)。
次のプログラムは、クリックすると音が鳴るドアベルです。
DoorBell
クラスで形を描くメソッド display()
とクリック位置の当たり判定をするメソッド contains()
が定義されています。
// A sound file object
let dingdong;
// A doorbell object (that will trigger the sound)
let doorbell;
function setup() {
createCanvas(200, 200);
dingdong = loadSound('bell.mp3');
// Create a new doorbell
doorbell = new Doorbell(width/2, height/2, 64);
}
function draw() {
background(255);
// Show the doorbell
doorbell.display(mouseX, mouseY);
}
function mousePressed() {
// If the user clicks on the doorbell, play the sound!
if (doorbell.contains(mouseX, mouseY)) {
dingdong.play();
}
}
// A Class to describe a "doorbell" (really a button)
class Doorbell{
// Location and size
constructor(x_, y_, r_){
this.x = x_;
this.y = y_;
this.r = r_;
}
// Is a point inside the doorbell? (used for mouse rollover, etc.)
contains(mx, my) {
if (dist(mx, my, this.x, this.y) < this.r) {
return true;
} else {
return false;
}
}
// Show the doorbell
display(mx, my) {
fill(175);
stroke(0);
strokeWeight(4);
circle(this.x, this.y, this.r);
}
}
その他のライブラリを調べる
カメラや音声以外でも、たくさんのライブラリを使うことができます。 どんなものがあるかはライブラリの枠から一覧を見ることができ、またライブラリ名から直接その説明ページへ飛びます。
練習問題
練習1
マイクから音声を拾い、その音量をきっかけに動きが変化するアニメーションを作ってください。 思いつかなければ、以下から一つを選んで実装してください。
- 拍手をするとボールが動き出す
- 声を出しているあいだだけアニメーションが進行する
練習2
次回から最終課題の制作です。 どんなライブラリがあるかを確認し、役立ちそうなものを見つけたら使い方などを調べましょう。(この問題は採点の対象外です。)