lecture:design_with_prototyping:p5.js編:11.ピクセル再構成

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
lecture:design_with_prototyping:p5.js編:11.ピクセル再構成 [2021/02/28 14:52] – [Sample05] babalecture:design_with_prototyping:p5.js編:11.ピクセル再構成 [2021/05/11 15:25] (現在) – [Sample04] baba
行 126: 行 126:
     for (let j = 0; j < sample_image.width; j++) {     for (let j = 0; j < sample_image.width; j++) {
       let c = sample_image.get(j, i);       let c = sample_image.get(j, i);
-      let gray = (blue(c)+green(c)+blue(c))/3;+      let gray = (red(c)+green(c)+blue(c))/3;
       stroke(gray);       stroke(gray);
       point(j, i);       point(j, i);
行 209: 行 209:
   * https://p5js.org/reference/#/p5/filter   * https://p5js.org/reference/#/p5/filter
 のリンクにあるように例えば次のようなコードを記述することでぼかし効果を簡単にえることもできます。 のリンクにあるように例えば次のようなコードを記述することでぼかし効果を簡単にえることもできます。
 +{{ :lecture:design_with_prototyping:p5.js編:11-閑話休題.png |}}
 <file .js sketch.js> <file .js sketch.js>
 var sample_image; var sample_image;
行 231: 行 232:
 <WRAP clear/> <WRAP clear/>
 ====== 対象物を表現するには ====== ====== 対象物を表現するには ======
-ここまでサンプルは抽象的な画像をいてましたが,少し具体的な下記画像変えみたいと思います. +私達が見ているは,画像のピクセの集合体です.画面におけるピクセルとは画像を表示するための最小単位になっています.単位について考えてみす.単位とはなんでょうか?なにかものを表すめの基準となる目盛りのことです.ではその基準は誰決めるのか.それはエンジニアであったりデザイナであったりアーティストであったり研究者であったり.単位はそれを表す上で実は自由決めものでもあります.その証拠に,オーム(Ω)やニュート(N),アンペア(A),テスラ,ボト,ベクレル,ヘルツどその単位を定義付けた科学者の名前がそのまま単位になってい事例が少なからず知られています.
-{{ :lecture:design_with_prototyping:img_3922.jpg?nolink&original | サなる画像}}+
  
 +単位とは量を把握するための単なる仕組みであり、私達はこれを客観的な手法からときには超主観的な場合にもこの単位を利用して世界にアクセスしています。単位に関して個人的な短い記事を書いておいたので以下をお読みください。
 +  * 単位について:https://note.com/interfacedesign/n/n5f9adf0bfc8e
  
-私達が見ているのは,画像のピクセルの集合体です.画面におけるピクセルとは画像を表示するための最小単位になっています. +さて画素単位は1ピクセルです.ではここで,10x10ピクセルを1単位として考えてみます.一つの画素を一つの単位として考えるのではなく,10の画素を一つ単位として考えます.10ピクセルごとに丸で描画してみると,目の細かいモザイクのような効果になりました. 
-単位について考えてみます.単位とはなんでしょうか?なにかものを表すための基準となる目盛りのことです.ではその基準は +{{ :lecture:design_with_prototyping:p5.js編:11-2-sample01.png |}} 
-誰が決めるのか.それはエンジニアであったりデザイナであったりアーティストであったり,研究者であったり.単位はそれを +<file .js sketch.js
-表す上で実は自由に決めて良いものでもあります.その証拠に,オーム(Ω)やニュートン(N),アンペア(A),テスラ,ボルト, +var sample_image
-ベクレル,ヘルツなどその単位を定義付けた科学者の名前がそのまま単位になっている事例が少なからず知られています. +  
- +function preload() { 
-上記で見ている画像はニューヨークのセントラルパーク前の横断歩道前で私が撮影した画像です.800x597のピクセル数で構成 +  sample_image = loadImage("seurat.png"); 
-おり,画素単位は1ピクセルです.ではここで,10ピクセルを1単位として考えてみます.一つの画素を一つの単位として考えるのではなく,10の画素を一つ単位として考えます. +
- +  
-{{ :lecture:design_with_prototyping:pixel_recomposition01.png?original |}} +function setup() { 
-<file .pde sample07.pde+  createCanvas(500336); 
-PImage img+   
-img = loadImage("sample.jpg"); +  noLoop(); 
-size(800597); +
-imageMode(CENTER); +  
-noStroke(); +function draw() { 
-background(255); +  background(0); 
-for ( int i = 0; i < img.height; i=i+10 ) { +  
-  for ( int j = 0; j < img.width; j=j+10 ) { +  for (let i = 0; i < sample_image.height; i+=10) { 
-    color c = img.get(j, i); +    for (let j = 0; j < sample_image.width; j+=10) { 
-    stroke(red(c), green(c), blue(c)); +      let c = sample_image.get(j, i); 
-    fill(red(c),green(c),blue(c));     +      stroke(c); 
-    strokeWeight(10); +      strokeWeight(10); 
-    point(j, i);+      point(j, i); 
 +    }
   }   }
 } }
 </file> </file>
  
-<WRAP center round tip 60%> 
-上記のプログラムを setup(), draw()で下記直し,tweakモードで実行してみましょう.それぞれforループにあるi, jの増加数を変化させることで画像がどのように変わるかを観察してみよう. 
-</WRAP> 
  
  
-10ピクセルごとに丸で描画してみると,目の細かいモザイクのような効果になりました.ではこの10ピクセル分の塊を別の単位に置き換えてみましょう. +===== 文字を単位にしてみる =====
-文字'A'を単位にしてみます.+
  
-{{ :lecture:design_with_prototyping:pixel_recomposition02.png?original |}} +この10ピクセル分の塊を別の単位に置き換えてみましょう. 
-<file .pde sample08.pde+文字'A'を単位にしてみます. 
-PImage img+{{ :lecture:design_with_prototyping:p5.js編:11-2-sample02.png |}} 
-img = loadImage("sample.jpg"); +<file .js sketch.js
-size(800597); +var sample_image
-imageMode(CENTER); +  
-noStroke(); +function preload() { 
-background(255); +  sample_image = loadImage("seurat.png"); 
-for ( int i = 0; i < img.height; i=i+10 ) { +
-  for ( int j = 0; j < img.width; j=j+10 ) { +  
-    color c = img.get(j, i); +function setup() { 
-    fill(red(c),green(c),blue(c));     +  createCanvas(500336); 
-    text("A",j,i);+   
 +  noLoop(); 
 +
 +  
 +function draw() { 
 +  background(255); 
 +  
 +  for (let i = 0; i < sample_image.height; i+=10) { 
 +    for (let j = 0; j < sample_image.width; j+=10) { 
 +      let c = sample_image.get(j, i); 
 +      fill(c)
 +      strokeWeight(0)
 +      textSize(10); 
 +      text('A',j,i); 
 +    }
   }   }
 } }
 </file> </file>
  
-====== 文字の複雑さを濃度として考え、ピクセルを描画する ======+ 
 +<WRAP center round todo 60%> 
 +<code> 
 +let char_typed; 
 +function keyPressed(){ 
 +  char_typed key; 
 +
 +</code> 
 +というコードをsketch.jsに追記してあげると入力した文字を char_typed というグローバル変数に保存しておくことができます。これを利用してA以外の文字でピクセル表示に切り替えられるようにプログラムを書き換えて見ましょう。 
 +</WRAP> 
 + 
 + 
 +===== 文字の複雑さを濃度として考え、ピクセルを描画する =====
 いわゆるアスキーアートと呼ばれる手法です。ピクセルに対応する濃度を文字種に変換することで、文字だけで絵を表現する独特の手法になります。ここまでですでに各ピクセルの明るさ情報は取得できているので、それを利用してどの文字を利用するのが良いかがわかれば実装ができそうです。[[http://paulbourke.net/dataformats/asciiart/|Character representation of grey scale images]]という1997年に書かれたサイトには、白と黒の明るさを文字種に対応させた一覧が載せられています。 いわゆるアスキーアートと呼ばれる手法です。ピクセルに対応する濃度を文字種に変換することで、文字だけで絵を表現する独特の手法になります。ここまでですでに各ピクセルの明るさ情報は取得できているので、それを利用してどの文字を利用するのが良いかがわかれば実装ができそうです。[[http://paulbourke.net/dataformats/asciiart/|Character representation of grey scale images]]という1997年に書かれたサイトには、白と黒の明るさを文字種に対応させた一覧が載せられています。
   char[] char_pixel = {'$', '@', 'B', '%', '8', '&', 'W', 'M', '#', '*', 'o', 'a', 'h', 'k',    char[] char_pixel = {'$', '@', 'B', '%', '8', '&', 'W', 'M', '#', '*', 'o', 'a', 'h', 'k', 
行 297: 行 322:
 上記の配列を利用して、真っ暗だと '$' を、真っ白だと ' ' を表示するプログラムを記述します。ポイントとしては 上記の配列を利用して、真っ暗だと '$' を、真っ白だと ' ' を表示するプログラムを記述します。ポイントとしては
   * 0-255 のピクセルbrightnessを 0 - (char_pixel.length-1)のサイズに変換する   * 0-255 のピクセルbrightnessを 0 - (char_pixel.length-1)のサイズに変換する
-  * brightness(c1)とすることで、輝度情報を取得できる+  * brightness(c)とすることで、輝度情報を取得できる
  
 の2つを追記できれば良いかなと思います。下記画像をよく見ると小さな文字だけで構成されているのがわかるかと思います。 の2つを追記できれば良いかなと思います。下記画像をよく見ると小さな文字だけで構成されているのがわかるかと思います。
  
-{{ :lecture:design_with_prototyping:output_sample08_2.png |}} +{{ :lecture:design_with_prototyping:p5.js編:11-2-sample04.png |}} 
-<file .pde sample08_2.pde+<file .js sketch.js
-import processing.video.*+var sample_image
-char[] char_pixel = {'$', '@', 'B', '%', '8', '&', 'W', 'M', '#', '*', 'o', 'a', 'h', 'k', + 
 +const char_pixel = ['$', '@', 'B', '%', '8', '&', 'W', 'M', '#', '*', 'o', 'a', 'h', 'k', 
   'b', 'd', 'p', 'q', 'w', 'm', 'Z', 'O', '0', 'Q', 'L', 'C', 'J', 'U', 'Y', 'X', 'z',    'b', 'd', 'p', 'q', 'w', 'm', 'Z', 'O', '0', 'Q', 'L', 'C', 'J', 'U', 'Y', 'X', 'z', 
   'c', 'v', 'u', 'n', 'x', 'r', 'j', 'f', 't', '/', '|', '(', ')', '1', '{', '}', '[', ']',    'c', 'v', 'u', 'n', 'x', 'r', 'j', 'f', 't', '/', '|', '(', ')', '1', '{', '}', '[', ']', 
-  '?', '-', '_', '+', '~', '<', '>', 'i', '!', 'l', 'I', ';', ':', ',', '<', '^', '`', '.', ' ' };+  '?', '-', '_', '+', '~', '<', '>', 'i', '!', 'l', 'I', ';', ':', ',', '<', '^', '`', '.', ' ' ];
  
-PImage img; +function preload() { 
-size(800, 597); +  sample_image = loadImage("seurat.png"); 
-img = loadImage("sample.jpg"); +} 
-imageMode(CENTER); +  
-noStroke(); +function setup() { 
-print(char_pixel.length); +  createCanvas(500, 336); 
-textSize(5); +   
- +  noLoop(); 
-noFill(); +} 
-background(0);   +  
-for ( int i = 0; i < img.height; i=i+5 ) { +function draw() { 
-  beginShape(); +  background(0); 
-  for ( int j = 0; j < img.width; j=j+) { +  
-    color c1 img.get(j, i); +  for (let i = 0; i < sample_image.height; i+=2) { 
-    float brightness = map(brightness(c1), 0, 255, 0, char_pixel.length-1); +    for (let j = 0; j < sample_image.width; j+=2) { 
-    text(char_pixel[int(brightness)], j, i);+      let c sample_image.get(j, i); 
 +      let pos parseInt(map(brightness(c),  
 +                    0,255, 0,char_pixel.length-1)); 
 +      fill(255); 
 +      textSize(2); 
 +      text(char_pixel[pos],j,i); 
 +    }
   }   }
-  endShape(); 
 } }
- 
 </file> </file>
  
  
 ===== 線で表現する ===== ===== 線で表現する =====
-<WRAP center round tip 60%> +上記ピクセルをベース対象物を再構成しみましたが,次は線を用てみます.テレビの走査線のよう左から右へ向けて黒い線を引ます。ただただ真っ直ぐな線では真っ黒なキャンバスができあがるだけですで、画素の明さ(brightness)に応じて線少し上方向にずらして描画してみると、以下のような出力結果を得ることができす。すこ不思議な画像になりましたね。このサンプルではパラメータを調整できるよに,index.htmlファイルも編集しているので、そちらの修正も同時に行ってください。
-以下のサンプルプログラムsetup(), draw()の内プログラムなっています.自分でvoid setup(){} void draw(){}て +
-tweakモード実行しつつ,プログラム舞い観察してみまし. +
-</WRAP>+
  
-上記はピクセルをベースに対象物を再構成してみましたが,次は線を用いてみます. +{{ :lecture:design_with_prototyping:p5.js編:11-line01.png?nolink |11-line01.png}} 
-{{ :lecture:design_with_prototyping:pixel_sample10.png?nolink |}} +<WRAP group> 
-<file .pde sample09.pde+<WRAP half column> 
-PImage img+ 
-img = loadImage("sample.jpg"); +<file .js sketch.js
-size(800597); +var sample_image
-imageMode(CENTER); +let x_step, y_step, y_max; 
-noFill(); + 
-background(255); +function preload() { 
-for( int i = 0; i < img.height; i+){ +  sample_image = loadImage("seurat.png"); 
-   +
-  beginShape(); + 
-  for( int j = 0; j < img.width; j+){ +function setup() { 
-    color c = img.get(j,i); +  createCanvas(500336); 
-    float gray (red(c)+green(c)+blue(c))/3+  select('#x_step').changed(xChanged); 
-    stroke(0,0,0); +  select('#y_step').changed(yChanged); 
-    vertex(j,i-gray/10.0);+  select('#y_max').changed(maxChanged); 
 +  x_step = select('#x_step').value(); 
 +  y_step = select('#y_step').value(); 
 +  y_max = select('#y_max').value(); 
 +  noLoop(); 
 +
 + 
 +function draw() { 
 +  background(255); 
 +  stroke(0); 
 +  for (let i = 0; i < sample_image.height; i += y_step) { 
 +    beginShape(); 
 +    for (let j = 0; j < sample_image.width; j += x_step) { 
 +      let c = sample_image.get(j, i); 
 +      let b brightness(c); 
 +      b = map(b, 0, 255, 0, y_max); 
 +      vertex(j, i - b); 
 +    } 
 +    endShape();
   }   }
-  endShape();+
 + 
 +function xChanged() { 
 +  x_step = this.value(); 
 +  draw(); 
 +
 + 
 +function yChanged() { 
 +  y_step = this.value(); 
 +  draw(); 
 +
 + 
 +function maxChanged() { 
 +  y_max = this.value(); 
 +  draw();
 } }
 </file> </file>
 +</WRAP>
 +
 +<WRAP half column>
 +<file .html index.html>
 +<!DOCTYPE html>
 +<html lang="en">
 +  <head>
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
 +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
 +    <link rel="stylesheet" type="text/css" href="style.css">
 +    <meta charset="utf-8" />
 +
 +  </head>
 +  <body>
 +    <script src="sketch.js"></script>
 +    x_step:<input type="range" id="x_step" value="1", min="1", max="10"><br>
 +    y_step:<input type="range" id="y_step" value="1", min="1", max="10"><br>
 +    y_max:<input type="range" id="y_max" value="5" min="0" max="50"><br>
 +
 +  </body>
 +</html>
 +
 +</file>
 +</WRAP>
 +</WRAP>
 +
 +
  
 ここで少し工夫している箇所は vertex 関数において,ただ座標を正しくうつのではなく,その画素の ここで少し工夫している箇所は vertex 関数において,ただ座標を正しくうつのではなく,その画素の
 グレースケール値に基づいて上下に位置を動かしていることです.これにより明るめの画素は上方向に座標が グレースケール値に基づいて上下に位置を動かしていることです.これにより明るめの画素は上方向に座標が
-移動し,暗めの画素は下方向に画素が移動します.上記プログラムはそれを画像サイズの縦ピクセル分すべて +移動し,暗めの画素は下方向に画素が移動します.
-描画していますが,これを少し間引いて下記のようなプログラムに変更してみます.これまで i++ としてた +
-ものを i=i+5 と変更したのみです. +
-{{ :lecture:design_with_prototyping:piel_sample11.png?nolink |}} +
-<file .pde sample10.pde> +
-PImage img; +
-img = loadImage("sample.jpg"); +
-size(800, 597); +
-imageMode(CENTER); +
-noFill(); +
-background(255); +
-for( int i = 0; i < img.height; i=i+5 ){ // 変更箇所 +
-   +
-  beginShape(); +
-  for( int j = 0; j < img.width; j++ ){ +
-    color c = img.get(j,i); +
-    float gray = (red(c)+green(c)+blue(c))/3; +
-    stroke(0,0,0); +
-    vertex(j,i-gray/10.0); +
-  } +
-  endShape(); +
-+
-</file>+
  
 +==== 線の本数や頂点座標のずらし方を変更してみる ====
 次はプログラムを少し最初に戻して,描く線にアルファ値をもたせてみます.アルファ値とは 次はプログラムを少し最初に戻して,描く線にアルファ値をもたせてみます.アルファ値とは
-透明度のことで,詳細は https://processing.org/tutorials/color/ を参照すると+透明度のことで,詳細は https://p5js.org/reference/#/p5/alpha を参照すると
 よいでしょう. よいでしょう.
  
-この透明度を利用し,これまで真っ黒で書いていた線に対して一定の透明度をつけてみます. +この透明度を利用し,これまで真っ黒で書いていた線に対して一定の透明度(stroke(0,0,0,100);をつけてみます. 
-実行結果とプログラムは下記の通りです.面白いことに結果として得られた画像は,デプスマップ(深度情報) +実行結果とプログラムは下記の通りです.面白いことに結果として得られた画像は,凹凸がつい銀盤のように見えますね。なお下記画像のパラメータは 
-を持っ画像のように見えますね+  * x_step = 1; 
 +  * y_step = 1; 
 +  * y_max = 5; 
 +としています。
  
-{{ :lecture:design_with_prototyping:pixel_sample12.png?nolink |}} +{{ :lecture:design_with_prototyping:p5.js編:11-line-sample03.png?nolink |}} 
-<file .pde sample12.pde> + 
-PImage img; + 
-img = loadImage("sample.jpg"); +<WRAP center round tip 60%> 
-size(800, 597); +ここまで学習した内容から、単位を別のなにかに置き換えることでスーラの絵画を再構成してください。 
-imageMode(CENTER); +  * Hint 
-noFill(); +    * 文字をピクセルにしたように、様々な文字(漢字やカタカナ等)も単位として表現しても良いかもしれません 
-background(255); +    * beginShape()にLINESやTRIANGLE_FAN等を使って表示した場合どのようになるか試してみると良いかもしれません。 
-for( int i = 0; i img.height; i++ ){ +    * 出力した結果がもとの絵からかけ離れてしまっても面白いかもしれません。 
-   +</WRAP>
-  beginShape(); +
-  for( int j = 0; j < img.width; j++ ){ +
-    color c = img.get(j,i); +
-    float gray = (red(c)+green(c)+blue(c))/3; +
-    stroke(0,0,0,100); +
-    vertex(j,i-gray/10.0); +
-  } +
-  endShape(); +
-} +
-</file>+
  
  • /home/users/2/lolipop.jp-4404d470cd64c603/web/ws/data/attic/lecture/design_with_prototyping/p5.js編/11.ピクセル再構成.1614491522.txt.gz
  • 最終更新: 2021/02/28 14:52
  • by baba