クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

【p5.js】Generative Design with p5.js「画像 P_4_1_2_01、02」のコードを読み解く

p5.jsの続きです。前回は「Generative Design with p5.js」の「文字 P_3_1_2_01」を見ました。今回は「画像 P_4_1_2_01、02」を見ていきます。それでは行きましょう!

【目次】

※参考:前回記事
【p5.js】Generative Design with p5.js「文字 P_3_1_2_01」のコードを読み解く - クモのようにコツコツと

※参考:p5.jsを習得するためにやったことまとめ
qiita.com

画像 P_4_1_2_01

書籍「Generative Design with p5.js」より

ソースコード一覧
※参考:Generative Design with p5.js[p5.js版ジェネラティブデザイン] ―ウェブでのクリエイティブ・コーディング

画像 P_4_1_2_01

時間と共に画像の上下位置がズレていく。水彩画に雨がかかったみたいな感じか。

※参考:p5.js Web Editor

JSコード全体

// P_4_1_2_01
//
// Generative Gestaltung – Creative Coding im Web
// ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018
// Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni
// with contributions by Joey Lee and Niels Poldervaart
// Copyright 2018
//
// http://www.generative-gestaltung.de
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * image feedback process.
 *
 * KEYS
 * del, backspace      : clear screen
 * s                   : save png
 */
'use strict';

var img;

function preload() {
  img = loadImage('data/pic.png');
}

function setup() {
  createCanvas(1024, 780);
  image(img, 0, 100);
}

function draw() {
  var x1 = floor(random(width));
  var y1 = 50;

  var x2 = round(x1 + random(-7, 7));
  var y2 = round(y1 + random(-5, 5));

  var w = floor(random(10, 40));
  var h = height - 100;

  set(x2, y2, get(x1, y1, w, h));
}

function keyReleased() {
  if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png');
  if (keyCode == DELETE || keyCode == BACKSPACE) {
    clear();
    image(img, 0, 100);
  }
}

冒頭コメントの前半はクレジット。 後半の概要の訳。

画像フィードバックプロセス。

キー del、backspace:画面をクリア s:pngを保存

全体構成

// グローバル変数

function preload() {
  // ページ読み込み前の処理
}

function setup() {
  // ページ読み込み時の処理
}

function draw() {
  // 一定時間ごとに繰り返し実行
}

function keyReleased() {
  // 文字キーを離した時の処理
}

グローバル変数

冒頭のグローバル変数の設定。

var img;

変数imgの宣言のみ。値はまだない。

preload():ページ読み込み前の処理

preload()メソッドはページ読み込み前の処理

function preload() {
  img = loadImage('data/pic.png');
}

imgloadImage()pic.pngをロード。

setup():ページ読み込み時の処理

setup()メソッドはページ読み込み時の処理

function setup() {
  createCanvas(1024, 780);
  image(img, 0, 100);
}
  • createCanvas()で幅1024px、高さ780pxのキャンバスを作成
  • image()imgを読み込む。上横位置0px、縦位置100px

draw():一定時間ごとに繰り返し実行

draw()メソッドは一定時間ごとに繰り返し実行

function draw() {
  var x1 = floor(random(width));
  var y1 = 50;

  var x2 = round(x1 + random(-7, 7));
  var y2 = round(y1 + random(-5, 5));

  var w = floor(random(10, 40));
  var h = height - 100;

  set(x2, y2, get(x1, y1, w, h));
}

ボリュームがあるのでブロックごとに見ていく。

  var x1 = floor(random(width));
  var y1 = 50;
  • 変数x1floor()メソッド、その引数でrandom()メソッドを実行(引数はwidth
  • 変数y1は50

floor()は小数点切り捨て、random()は乱数。引数が一つの場合は0からその数値までの乱数。

If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number.

1つの引数が指定され、それが数値の場合、0から(数値を含まない)までの乱数を返します。

widthはキャンバス幅。

※参考:reference | p5.js

  var x2 = round(x1 + random(-7, 7));
  var y2 = round(y1 + random(-5, 5));
  • 変数x2round()メソッド実行。引数はx1足すrandom()(-7〜7の間)
  • 変数y2round()メソッド実行。引数はy1足すrandom()(-5〜5の間)

round()は近い整数を出すメソッド。四捨五入みたいな感じか。

Calculates the integer closest to the n parameter. For example, round(133.8) returns the value 134. Maps to Math.round().

nパラメータに最も近い整数を計算します。 たとえば、round(133.8)は値134を返します。Math.round()にマップします。

※参考:reference | p5.js

  var w = floor(random(10, 40));
  var h = height - 100;
  • 変数wfloor()メソッド、その引数でrandom()メソッドを実行(引数は10〜40)
  • 変数hでキャンバス高さheight引く100
  set(x2, y2, get(x1, y1, w, h));
  • set()メソッド実行:引数は左からx2, y2, get()メソッド(引数はx1, y1, w, h

set()は画像の書き込み。

Changes the color of any pixel, or writes an image directly to the display window.

任意のピクセルの色を変更するか、画像を表示ウィンドウに直接書き込みます。

引数の意味。

set(x, y, c)

x Number: x-coordinate of the pixel
y Number: y-coordinate of the pixel
c Number|Number[]|Object: insert a grayscale value | a pixel array | a p5.Color object | a p5.Image to copy

set(x, y, c)

x番号:ピクセルのx座標  
y番号:ピクセルのy座標  
c数値|数値[] |オブジェクト:グレースケール値を挿入| ピクセル配列| p5.Colorオブジェクト| コピーするp5.Image

※参考:reference | p5.js

第1引数がx2、第2引数がy2、第3引数はget()

get()は画像の取得。

※参考:【p5.js】Generative Design with p5.js「画像 P_4_1_1_01」のコードを読み解く - クモのようにコツコツと

引数は横位置x1, 縦位置y1, 幅w, 高さh

random()メソッドが入っている箇所はフレームごとにランダムな結果を返している。

keyReleased():文字キーを離した時の処理

keyReleased()メソッドは文字キーを離した時の処理

function keyReleased() {
  if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png');
  if (keyCode == DELETE || keyCode == BACKSPACE) {
    clear();
    image(img, 0, 100);
  }
  • もしkeysまたはSならばキャンバスをpng画像で保存
  • もしkeyCodeDELETEまたはBACKSPACEならば
    clear()メソッドを実行
    image()メソッドを実行(引数はimg, 0, 100

一つ目のif文はいつもの画像保存。

二つ目のif文はリセット設定。

clear()はピクセル描画をクリア。

※参考:【p5.js】Generative Design with p5.js「色 P_2_1_1_01、02」のコードを読み解く - クモのようにコツコツと

おまけ:画像 P_4_1_2_02

上記とよく似た「P_4_1_2_02」がある。

今度は縦長ではなく長方形の画像がランダムに再配置されている。こちらの方が印象派の絵画っぽくてアーティスティック♪

JSコード全体

// P_4_1_2_02
//
// Generative Gestaltung – Creative Coding im Web
// ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018
// Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni
// with contributions by Joey Lee and Niels Poldervaart
// Copyright 2018
//
// http://www.generative-gestaltung.de
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * image feedback process.
 *
 * KEYS
 * del, backspace      : clear screen
 * s                   : save png
 */
'use strict';

var img;

function preload() {
  img = loadImage('data/pic.png');
}

function setup() {
  createCanvas(1024, 780);
  image(img, 0, 0);
}

function draw() {
  var x1 = random(width);
  var y1 = random(height);

  var x2 = round(x1 + random(-10, 10));
  var y2 = round(y1 + random(-10, 10));

  var w = 150;
  var h = 50;

  set(x2, y2, get(x1, y1, w, h));
}

function keyReleased() {
  if (key == 's' || key == 'S') saveCanvas(gd.timestamp(), 'png');
  if (keyCode == DELETE || keyCode == BACKSPACE) {
    clear();
    image(img, 0, 0);
  }
}

変わったのはdraw()メソッド部分

function draw() {
  var x1 = random(width);
  var y1 = random(height);

  var x2 = round(x1 + random(-10, 10));
  var y2 = round(y1 + random(-10, 10));

  var w = 150;
  var h = 50;

  set(x2, y2, get(x1, y1, w, h));
}
  • y1が固定数値ではなくrandom()に(引数はheight
  • wrandom()ではなく固定数値に

これによって縦長ではなく長方形のランダム画像が切り取られて再配置されるように!

最後に

f:id:idr_zz:20200712153655p:plain

改めて、乱数(random())を使うと面白いものが作れるなーと。これはp5.jsに限ったことではなく、要は使い方、アイデアなんだろうけど。そして無尽蔵なランダムではなく範囲やしきい値を指定することで想定される結果をコントロールしたり。自分もそういうものを作ってみたいと感じさせられました。

さて、「Generative Design」シリーズは今回で「色」「形」「文字」「画像」編をそれぞれ3つずつ記事化しました。このまま全てのコードを見て行こうと思っていたのですが、ここら辺でいったん一区切りにしようかと思います。

お陰様でp5.jsの概要は掴めてきたので、今後はこれまでの経験をもとに自分でゼロから何かを作るフェーズに入っていこうと思っています。それではまた!


※参考:p5.jsを習得するためにやったことまとめ
qiita.com